Hi –
On Fri, 16 Dec 2005, [email protected] wrote:
On Dec 15, 2005, at 5:41 PM, [email protected] 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
[email protected]
“Ruby for Rails: Ruby techniques for Rails developers”,
coming April 2006 (Ruby for Rails)