From: Logan Capaldo Date: 2006-08-01T11:50:28+09:00 Subject: Re: I thought this was the one that worked? On Jul 31, 2006, at 10:30 PM, Chad Perrin wrote: > On Tue, Aug 01, 2006 at 09:50:23AM +0900, Logan Capaldo wrote: >> >> On Jul 31, 2006, at 6:48 PM, Chad Perrin wrote: >> >>> On Tue, Aug 01, 2006 at 07:05:31AM +0900, Logan Capaldo wrote: >>>> >>>> On Jul 31, 2006, at 5:13 PM, Chad Perrin wrote: >>>> >>>>> On Tue, Aug 01, 2006 at 04:57:48AM +0900, Logan Capaldo wrote: >>>>>> >>>>>> All these examples are lexical scoping. Ruby doesn't really have >>>>>> dynamic scoping although you can sort of abuse instance >>>>>> variables to >>>>>> achieve similar effects. >>>>>> >>>>>> The difference is that blocks are closures, where def, class, and >>>>>> module aren't. >>>>> >>>>> Wait . . . you mean that *all blocks* are automagically lexical >>>>> closures, as though declared lexical variables within them have >>>>> gone out >>>>> of scope? I imagine I'm probably misunderstanding you, but if >>>>> not, >>>>> that's a pretty nifty bit of trickery. >>>>> >>>> I'm not sure I understand your question. All blocks (by blocks I >>>> mean >>>> do / end and { } ) are (lexically scoped) closures. >>> >>> I'll use a Perl example: >>> >>> sub foo { >>> my $bar = 1; >>> return sub { print ++$bar }; >>> } >>> >>> my $baz = foo(); >>> >>> Voila. $baz contains a lexical closure. This is the case >>> because the >>> return value from foo() was lexically "closed" by virtue of $bar >>> going >>> out of scope, but its value still being accessible via the coderef >>> returned from foo() and assigned to $baz. >>> >> >> Yes. It is just like perl. >> >> % cat closure.rb >> def foo >> bar = 1 >> lambda { puts (bar += 1) } >> end >> >> baz = foo() >> >> baz.call >> baz.call >> >> % ruby closure.rb >> -:13: warning: don't put space before argument parentheses >> 2 >> 3 > > Okay. Looks like a closure. It looks like a closure because of the > relationship of bar to the return-value block of code. I've been told > that all blocks are closures, though -- and I don't see how it's > still a > closure if the "bar = 1" is removed from foo. > > -- > CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ] > "It's just incredible that a trillion-synapse computer could actually > spend Saturday afternoon watching a football game." - Marvin Minsky > Oh yeah, here's another example: def foo return lambda { puts eval("x") }, binding end closure, bnding = foo() eval("x = 7", bnding) closure.call Basically, it's impossible not to create a closure with a block in ruby, there is always an implicit closure.