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.
def foo
yield("Jim")
end
def bar
baz = lambda { |n| n.upcase }
foo(&baz)
end
bar # => "JIM"
From what I understand where this is going:
1. The method bar is being called.
Check.
2. 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.
3. 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@(irb):9>
(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"
4. 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
···
On Fri, Apr 12, 2013 at 10:12 PM, Vincent Stowbunenko <lists@ruby-forum.com>wrote:
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/