🪟 Windows TippsThe Gemini desktop app is now available for Windows(11.09.2026 um 17:06 Uhr)
🪟 Windows TippsHeader and Footer not showing in Excel(14.09.2026 um 22:43 Uhr)
🕵️ SicherheitslückenBurn Out, Or Fade Away(14.09.2026 um 14:25 Uhr)
🪟 Windows TippsKB5129194 Windows 11 26H1 Out of Band Update - Deskmodder.de(14.09.2026 um 19:25 Uhr)
🪟 Windows TippsThe Gemini desktop app is now available for Windows(11.09.2026 um 17:06 Uhr)
🪟 Windows TippsHeader and Footer not showing in Excel(14.09.2026 um 22:43 Uhr)
🕵️ SicherheitslückenBurn Out, Or Fade Away(14.09.2026 um 14:25 Uhr)
🪟 Windows TippsKB5129194 Windows 11 26H1 Out of Band Update - Deskmodder.de(14.09.2026 um 19:25 Uhr)

🔧 Programmierung 🕛 vor 2 Monaten 5 Min Lesezeit
0

Blocks, Procs, and the "&" Bridge

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

&blk in a parameter list turns a block into a Proc; &proc at a call turns a Proc back into a block.







1. A block is syntax, not an object



A block is the { ... } or do ... end you attach to a method call. It is not a value you can hold by itself.



You can't store a block in a variable — Ruby won't even parse it:




CODE
b = { |x| x * 2 }   # SyntaxError
# Ruby reads { } here as a hash, not a block.






A method can carry at most one block:




CODE
[1, 2, 3].each { |x| puts x }   # fine — exactly one block
# There is no syntax to attach a second block to the same call.






Inside a method you reach the block with yield:




CODE
def run
yield # runs whatever block was attached
yield # you can run it again
end
run { puts "hi" } # prints: hi hi






A block is not a normal argument. It rides along separately from the things in the parentheses:




CODE
def how_many(*args)
args.size
end
how_many(1, 2) { puts "ignored" } # => 2 (the block is NOT counted as an argument)









2. A Proc is an object



A Proc is a real object that holds a chunk of code. You can do anything with it that you do with any object.



Store it in a variable:




CODE
doubler = proc { |x| x * 2 } # or Proc.new { |x| x * 2 }
doubler.class # => Proc






Call it (three equivalent ways):




CODE
doubler.call(5)    # => 10
doubler.(5) # => 10 (.() shorthand)
doubler[5] # => 10 ([] shorthand)






Put it in an array and pass it around:




CODE
jobs = [proc { puts "a" }, proc { puts "b" }]
jobs.each { |job| job.call } # prints: a b






So the difference is simple: a block is loose syntax attached to one call; a Proc is an object you can keep.






3. & is the bridge between them



& converts a block into a Proc, or a Proc into a block. Which direction happens depends only on where you write the &.






3.a) & in the parameter list → block becomes a Proc



When you write def foo(&blk), the & catches the block the caller attached and gives it to you as a Proc object named blk:




CODE
def foo(&blk)
blk.class # => Proc (now it's a real object)
blk.call(10) # => 20 (call it like any object)
end
foo { |x| x * 2 } # the { } block arrives as the Proc `blk`






Without & you'd have no name for the block — you could only use yield. With &blk you can store it, inspect it, or pass it on.




CODE
def run
yield # the ONLY way to reach the block
# blk — there's no such variable to refer to
# @saved = blk — can't store it
# blk.arity — can't inspect it
# other(&blk) — can't pass it on
end
run { puts "hi" } # prints: hi









3.b) & at a call site → Proc becomes a block



When you already have a Proc in a variable and want a method to use it as its block, put & in front:




CODE
doubler = ->(x) { x * 2 }
[1, 2, 3].map(&doubler) # => [2, 4, 6]






Here doubler is lambda



Without the &, it's treated as a normal argument and map won't use it as the block:




CODE
[1, 2, 3].map(doubler)     # ArgumentError
# wrong number of arguments (given 1, expected 0)












lambda is a Proc



The arrow ->(x) { ... } just creates a Proc object that happens to be the "strict" kind. You can check:




CODE
doubler = ->(x) { x * 2 }
doubler.class # => Proc
doubler.lambda? # => true






So when the text says "a Proc in a variable", a lambda counts — it is a Proc. The word Proc (capital P) is the class; both ways of making one produce an object of that class:




CODE
a = ->(x) { x * 2 }       # lambda
b = lambda { |x| x * 2 } # lambda (same as above)
c = proc { |x| x * 2 } # plain proc
d = Proc.new { |x| x * 2 }# plain proc

[a, b, c, d].map(&:class) # => [Proc, Proc, Proc, Proc]
[a, b, c, d].map(&:lambda?) # => [true, true, false, false]












3.c) Both directions in one method



Capture a block as a Proc, then forward it as a block to another method. Same &, opposite jobs, decided purely by position:




CODE
def logged(&blk)          # & in params: block → Proc `blk`
puts "start"
[1, 2, 3].each(&blk) # & at call: Proc `blk` → block for each
puts "end"
end
logged { |n| puts n } # prints: start 1 2 3 end









4. The to_proc rule



One extra rule explains everything else: at a call site, if the thing after & is not already a Proc, Ruby first calls .to_proc on it, then turns the result into a block.



A Symbol knows how to become a Proc:




CODE
:upcase.to_proc.call("hi") # => "HI"

%w[a b c].map(&:upcase) # `&` runs `:upcase.to_proc`, then uses it as the block
%w[a b c].map { |s| s.upcase } # exactly the same thing
# both => ["A", "B", "C"]






So &:upcase is roughly the same as &->(x) { x.upcase }.



A Method object does too (remember: method(:name) returns an object):




CODE
method(:puts).class               # => Method
method(:puts).to_proc.call("hi") # prints: hi

[1, 2, 3].each(&method(:puts)) # `&` runs the Method's `to_proc`, then uses it
[1, 2, 3].each { |x| puts x } # exactly the same thing
# both print: 1 2 3






Even your own objects work after &, as long as they define to_proc:




CODE
class Multiplier
def initialize(by) = @by = by
def to_proc = proc { |x| x * @by }
end

triple = Multiplier.new(3)
[1, 2, 3].map(&triple) # => [3, 6, 9]









5. The whole thing in two lines





  • &X at a call means: take X, call .to_proc if it isn't already a Proc, then use it as the block.


  • &blk in a parameter list does the reverse — it catches the block and hands it back as a Proc you can hold.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
The Gemini desktop app is now available for Windows
1 Quelle
Header and Footer not showing in Excel
1 Quelle
Burn Out, Or Fade Away
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Blocks, Procs, and the "&" Bridge

Thematisch verwandte Begriffe: Blocks, Procs, Bridge · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...