Hi --

On Fri, 16 Dec 2005, gwtmp01 / mac.com wrote:

>
> On Dec 15, 2005, at 5:41 PM, dblack / wobblini.net wrote:
>> Except... they're not quite identical, and actually as of RubyConf
>> 2003 (I think) Matz agreed that 'proc' would be deprecated in favor of
>> 'lambda', because having something called proc and something called
>> Proc.new that weren't the same was confusing.
>
> This is an area that has been a bit fuzzy for me.

And for many of us :-)

> Is it fair to say that the only difference between
> 	Proc.new {#some code}
> and
> 	lambda {#some code}
>
> is the behavior when 'return' is explicitly called in the block?
> Are there any other differences?

I think the matter of arity strictness is still different.  Frankly I
could never remember the details, and I know that I am by no means
alone in this.  Basically, lambdas will give you an error if you send
them the wrong number of arguments.  Unless they take only one
argument, in which case you'll get a warning.  If the lambda takes no
arguments, then it doesn't care, unless the no-arguments is specified
with || (instead of just nothing), in which case you have to send
exactly zero arguments.

Procs are different.  They give you the warning sometimes, but I don't
think they ever raise an exception because of wrong number of
arguments.  (I really wish that warning would disappear.)

And so on.  I'm not making fun of it, though it may sound that way.  I
find it genuinely confusing, and it's a bit notorious for this.  If
anyone wishes to come along and claim that it's simple and easy to
remember, please provide instructions for remembering it :-)

> Am I correct in saying that when a formal argument list explicitly
> captures a block:
> 	def foo(&block);end
> that Ruby converts the actual block to a Proc instance via
> Proc.new as opposed to Kernel#lambda?

There's actually no Kernel#lambda (lambda is a keyword, not a method),
but yes, it becomes a Proc.  Although... if you do this:

   meth &lambda { ... }

it remains a lambda in the method (or so it appears from what irb is
telling me).

> And finally, is there a way to create a lambda-like object via
> a class method of Proc or is that behavior only available via
> Kernel#lambda?  I seems unusual that Kernel#lambda returns an
> instance of Proc but that there is no way to get Proc itself
> to generate that type of an object.

Well, lambda is a kind of specialization of Proc -- almost in the
spirit of being a subclass.  So Proc has no knowledge of that
specialization.  I agree that it should be of a different class.  I've
been seeing people (including myself) having a hard time keeping all
of this straight for years.  Not that the users have to be coddled :-)
but I think there's evidence that it is indeed confusing.


David

-- 
David A. Black
dblack / wobblini.net

"Ruby for Rails: Ruby techniques for Rails developers",
coming April 2006 (http://www.manning.com/books/black)