From: "Mauricio Fernández" Date: 2003-02-01T21:58:45+09:00 Subject: Re: local variables, blocks & self ambiguity (was Local variables & blocks) On Fri, Jan 31, 2003 at 09:26:28PM +0900, Tom Sawyer wrote: > On Thursday 30 January 2003 05:44 pm, ahoward wrote: > > yes. i have confused scope with namespaces, but not entirely i think. > > scope is a rather complex issue in Ruby, it seems. i was just thinking about > it myself in relation to the ambiguity between implied self method calls and > local variables (a pet subject of mine), which got me thinking: what would > the ramifications be if the scope at any point was always defined by self? > > x = 1 > closure = lambda { x } > > thus x in the closure would not be the same as the first x because self is > different in the two cases. i suppose this is essentially the same as the > poll option: make'em all local. so how do you get access to outer variables > from within closures in this scenario?... > > first, let me come back to the ambiguity between local variables and implied > self-receiver method calls. i've had an interesting conception about this: > what does it mean to do this when #x= is not defined? > > self.x = 1 > > no doubt, i would get an error saying #x= is undefined, correct? perhaps that > is an error in itself! ;-) why not have local variables themselves be a sort > of instantly instantiated "attr_accessor", albiet of a slighty different > nature than normal methods --in that ruby handles these "instant attributes" > as it currently does local variables. hmmm....ambiguity fading? Would these instant attributes live between method calls? class Bar def foo x = 1 end def foo2 puts x end end a = Bar.new a.foo a.foo2 # puts 1 ?? > now we come back to accessing outerscoped variables in our closure. our > problem is not yet solved, but can be with the realization thus: ruby has to > keep track of self at theses various descention/ascentions into blocks and > out again. correct? in essence this is a FIFO stack of what self is at any > given code point. so why not make self available for it what it really is: an > Array? self, stated by itself, would be the same as self[0], but > self[1]...ah... > > x = 1 > closure = lambda { self[1].x } > > would gives us the inter-related result: x in the outer scope is the same as > self[1].x in the inner scope. > > some interesting possibilities start to trickle into mind..... You possibly break GC, as blocks can access variables deeply down the stack, so you're in fact capturing a substantial part of the environment in each closure. def foo x = "a" * 100000 proc do |i| self[i].x # Ouch, self.x can never be reclaimed for any self down # the stack! end # normally x could be reclaimed here unless explicitly used by the # closure end def foo2 x = "b" * 100000 foo # normally x could be reclaimed here, but the closure might use it end foo.call(1) foo2.call(2) foo.call(100) # now, what was x 100 stack-frames ago? I had better never use self[i].tmp inside one of these super-closures :) Maybe I got it wrong, but I have the feeling this is too powerful. I'll think more on this. Now, I sound like matz ;-) These super-closures sure are very seductive :) -- _ _ | |__ __ _| |_ ___ _ __ ___ __ _ _ __ | '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ | |_) | (_| | |_\__ \ | | | | | (_| | | | | |_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_| Running Debian GNU/Linux Sid (unstable) batsman dot geo at yahoo dot com Ok, I'm just uploading the new version of the kernel, v1.3.33, also known as "the buggiest kernel ever". -- Linus Torvalds