Hi --

On Tue, 1 Aug 2006, Just Another Victim of the Ambient Morality wrote:

>
> <dblack / wobblini.net> wrote in message
> news:Pine.LNX.4.64.0608010845050.8390 / rubypal.com...
>>
>> You could say, though, that when you do this:
>>
>>   def x
>>     a = 1
>>     puts a
>>   end
>>
>>   def y
>>     x
>>   end
>>
>> you're calling x from your method y, and x has access to local
>> variables not defined in y, so x must be a closure.
>
>    Now you're narrowly construing my statement to a ludicrous degree.

I'm just discussing the topic at hand, I think.  It's really not about
this or that statement; I just like to examine things like this.

> There is context to what I said, you know?
>    In your example, method "x" has access to variable "a" because that
> variable is in its own context, not its _enclosing_ context.  This is a
> better example:
>
> a = 1
> def x
>    puts a
> end
>
> def y
>    x
> end
>
>
>    Then x _will_ be a closure but, then again, we already knew this...

But the a inside x and the a outside x are unrelated.  Method
definition blocks (with def) aren't closures.

>>>> It comes down to the fact that blocks are syntactic constructs, while
>>>> Procs are first-class objects.
>>>
>>>    I'm not sure why this has anything to do with anything...
>>
>> Consider an if statement:
>>
>>   y = 1
>>   if x
>>     y
>>   end
>>
>> The code in the middle is flat, as regards scope.  Furthermore, you
>> can't do anything with it; you can't send that chunk of code
>> somewhere, open it up, and find y.  It's just an expression or
>> statement among other expressions or statements.
>>
>> A code block has one foot in that camp.  When you see:
>>
>>   a = 10
>>   [1,2,3].each {|x| puts x * a }
>>
>> you're seeing, in a sense, a flat scope -- that is, the variable a
>> just gets used, as it might if it were in an if statement.
>
>    That's the whole point of closures.  It looks like variable "a" "just
> gets used," even though the process of it being used is quite complex.
>    If I understand what you mean by "flat," then it isn't flat.  It only
> _looks_ flat.

Right -- see the "other parts of the story", below.

>    Is this an example of "flat" scope?

Yes.

> a = "foo"
> b = a + "bar"
> puts b
>
>
>    It may look "flat" but scopes have come and gone.

I only see one local scope there.  Where do you see others?

>    Your example took a block and sent it to the method "each," which has
> it's own scope, where the block would have ordinarily had no hope of
> accessing the variable "a" except that it was a closure...

The part I'm not convinced of is "sent".  It provided a code block,
but it didn't send it.

>> That's only part of the story, though.  The other parts are, first,
>> that variables created inside the block are not in scope when the
>> block exits (so its scope is definitely not flat); and, second, the
>> fact that it's so easy to convert a block to a Proc that blocks feel
>> like first-class objects, even though they aren't.
>
>    I'm not certain that the other parts of "the story" are relevant.

See above; it's just different ways of looking at a block, or ways of
looking at different characteristics of a block.

>    Incidentally, having variables created inside the block be in scope when
> the block exits is planned for Ruby2.  Indeed, if memory serves me, it is
> Matz's "most regretting" design decision that it doesn't already do this...
> So, I guess it will then be "flat."
>    Personally, I look forward to this feature...

I'm among the few that like it the way it is, but I think we're on the
losing end of this decision-making process for 2.0 :-)


David

-- 
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
   ----> SEE SPECIAL DEAL FOR RUBY/RAILS USERS GROUPS! <-----
http://dablog.rubypal.com        => D[avid ]A[. ]B[lack's][ Web]log
http://www.manning.com/black     => book, Ruby for Rails
http://www.rubycentral.org       => Ruby Central, Inc.