Re: I thought this was the one that worked?
- From: dblack@xxxxxxxxxxxx
- Date: Tue, 1 Aug 2006 21:52:31 +0900
Hi --
On Tue, 1 Aug 2006, Just Another Victim of the Ambient Morality wrote:
<dblack@xxxxxxxxxxxx> wrote in message
news:Pine.LNX.4.64.0608010732450.7358@xxxxxxxxxxxxxx
<dblack@xxxxxxxxxxxx> wrote in message
news:Pine.LNX.4.64.0607312255430.32274@xxxxxxxxxxxxxx
Of course, not all blocks end up getting turned into Proc objects;
some remain just syntactic constructs:
a = 1
[1,2,3].each {|x| puts x + a }
I guess you could debate whether that block is a closure, since it
never leaves the context where it's created -- so there's nothing
really remarkable about the fact that a is still visible inside it.
And every time you put its closureness to the test, so to speak,
you've turned it into a Proc, so technically the Proc, rather than the
block, is the closure.
I would debate that it _is_ a closure because, although it's defined
where its context is, that's irrelevant. What matters is that the block
is
passed into the "each" method of the Array class and is executed there,
where "a" is not visible. Thus, the block was executed outside of the
scope
of "a" while still having access to it. How is this possible? It's
possible because the block that was passed in is a closure...
QED.
It's not exactly passed to the method, though. You can capture it in
the method -- in which case, it becomes a Proc object, and then
there's no issue (hair-splitting or otherwise) about its being a
closure.
If you don't capture it, you can yield to it -- but then you're
yielding to the block, not calling a Proc object derived from the
block.
...and this would be a problem if the definition of a closure is the
calling of a Proc object derived from a block. Alas, that is _not_ the
definition of a closure...
When we yield to the block, we are doing so in our method, which is
_not_ the same scope as the scope where the block was created. Yet, the
block we're yielding to still has access to that other scope. How? Because
it is a closure...
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.
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 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.
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.
.
- Follow-Ups:
- Re: I thought this was the one that worked?
- From: Just Another Victim of the Ambient Morality
- Re: I thought this was the one that worked?
- References:
- I thought this was the one that worked?
- From: Eric Armstrong
- Re: I thought this was the one that worked?
- From: Logan Capaldo
- Re: I thought this was the one that worked?
- From: Chad Perrin
- Re: I thought this was the one that worked?
- From: Logan Capaldo
- Re: I thought this was the one that worked?
- From: Chad Perrin
- Re: I thought this was the one that worked?
- From: Logan Capaldo
- Re: I thought this was the one that worked?
- From: Chad Perrin
- Re: I thought this was the one that worked?
- From: Logan Capaldo
- Re: I thought this was the one that worked?
- From: Chad Perrin
- Re: I thought this was the one that worked?
- From: dblack
- Re: I thought this was the one that worked?
- From: Just Another Victim of the Ambient Morality
- Re: I thought this was the one that worked?
- From: dblack
- Re: I thought this was the one that worked?
- From: Just Another Victim of the Ambient Morality
- I thought this was the one that worked?
- Prev by Date: Re: Question regarding postings in comp.lang.ruby
- Next by Date: Re: Signaling Ruby from C/C++
- Previous by thread: Re: I thought this was the one that worked?
- Next by thread: Re: I thought this was the one that worked?
- Index(es):
Relevant Pages
|