From: Christopher Dicely Date: 2009-03-07T11:54:33+09:00 Subject: Re: What's wrong with lambda and class On Fri, Mar 6, 2009 at 3:45 AM, lasitha wrote: > On Fri, Mar 6, 2009 at 4:50 PM, Brian Candler wrote: >> Actually, the question for me was "why 1?" in your second case. Passing >> a lambda as a block argument to a method is an odd thing to do; I >> believe it is being coerced to a block as if you did Proc.new(&c). > > That's what i'm trying to figure out, too. > If the lambda is being coerced, it isn't being honest about it: > > 01> def is_lambda?(&closure) > 02>   closure.lambda? > 03> end > 04> is_lambda? &(Proc.new { }) > --> false > 05> is_lambda? &(lambda { }) > --> true > > Perhaps it has more to do with rules around yield (or it's implementation)? > All i've dug up so far is this (unanswered) thread: > http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/22634 > > Been scanning the Pickaxe and Flannagan/Matz but haven't seen anything > definitive on this yet. The idea that it has to do with yield is basically right, though I'd describe it as having to do with blocks as distinct from instances of class Proc (procs or lambdas). When you yield to a block attached to a function -- which, you must keep in mind, isn't a proc or a lambda or even a normal Ruby object at all, its a different beast entirely though you can call a method with the method(&proc) notation to send a Proc instance (proc or lambda) to be wrapped in a block* -- it behaves like a proc (that is an object created with Proc.new {...} in any version of ruby, and also proc {...} in Ruby 1.9.x.) Both "lambda_and_yield" and "proc_and_yield", therefore, aren't yielding to lambdas or procs, the methods yield to a block in both cases, so the behavior is the same, and the same as it would be if you attached a block to the method call directly instead of supplying a Proc instance to wrap in a block by calling with the method(&proc) notation. * I've often seen it described as "treated as" or "converted to" a block, but its clear that it retains its identity, since if you define a method with def method(&block) to make a passed Proc instance or block accessible within the method body as a Proc instance, the local Proc instance is still a lambda if you passed in a lambda, which suggests to me that a call to the Proc instance gets wrapped in a block if the method doesn't use the &block argument pattern to get it as a Proc instance. The Pickaxe (2nd Ed.) does discuss the behavior of blocks, procs (which it calls "raw procs"), and lambdas in quite some detail, on pp. 356-360.