On Fri, Apr 12, 2013 at 10:12 PM, Vincent S.
[email protected]wrote:
I am confused about what is going on with this code:
IMO the most important aspect to remember about this is that a block is
an
anonymous function.
From what I understand where this is going:
- The method bar is being called.
Check.
- Inside the bar method, the lambda function is being assigned to the
baz variable, to upcase whatever is assigned to the variable n inside
the lambda function.
Check.
- I don’t understand the use of ampersand operator associated with the
variable baz. Whatever that is, it is an argument for the foo method.
The ampersand is used in two ways: one way presented by you here at the
calling site to pass a block (or something which implements #to_proc) to
a
method. The other one is inside methods to access the block as an
object:
irb(main):008:0> def f(&b) p b; yield 1; b.call(2); b[3] end
=> nil
irb(main):009:0> f {|x| printf “(%p)\n”, x}
#Proc:0x8b19358@:9(irb)
(1)
(2)
(3)
=> nil
When accessing the block as object it can be stored somewhere (e.g. in a
member variable) for later use. That’s the main advantage.
irb(main):010:0> o = Object.new
=> #Object:0x8b265e4
irb(main):011:0> def o.to_proc; lambda {|y| p y} end
=> nil
irb(main):012:0> f(&o)
#<Proc:0x8b3e810@(irb):11 (lambda)>
1
2
3
=> 3
#to_proc is a special mechanism which allows to pass arbitrary things as
a
block, for example:
irb(main):013:0> (1…4).map(&:to_s)
=> [“1”, “2”, “3”, “4”]
Here method #to_proc of the symbol “to_s” invoked. It returns a block
with
a single argument which invokes the method represented by the given name
on
the object:
irb(main):014:0> b = :to_s.to_proc
=> #Proc:0x8b4c4ec
irb(main):015:0> b.call 123
=> “123”
- Inside the foo method, it uses a yield function with an argument
“Jim”. Somehow, the string “Jim” made it way to assign to the variable
n, upcasing it.
Keyword “yield” is used to invoke a block passed to the method; since
the
method does not have a name there must be a standard way to invoke it.
The
other ways I have also shown in line 1 above.
A few other aspects
http://blog.rubybestpractices.com/posts/rklemme/001-Using_blocks_for_Robustness.html
http://blog.rubybestpractices.com/posts/rklemme/002_Writing_Block_Methods.html
Kind regards
robert