From: Jim Weirich Date: 2003-05-18T21:19:05+09:00 Subject: Re: An Object Going Out Of Scope On Sun, 2003-05-18 at 05:08, MikkelFJ wrote: > > "Jim Weirich" wrote in message > news:1053238069.6843.15.camel@traken... > > On Sun, 2003-05-18 at 00:47, vinita Papur wrote: > > > A quick question. How can one discern when an object goes out of scope? > > > I'd like to do something like this: > > > > Objects don't have scope. Variables do. (a subtle distinction) > > > Use a block to manage resources. Like this ... > > Still, it would actually be nice to have a feature in Ruby that would > trigger a finalizer when the variable goes out of scope. There are problems > becuase there could be more references at the time of finalization, but this > could also be the case with cleanup using structs. I.e. closing a file > doesn't guarantee there are no more references to the file. Just because a variable goes out of scope doesn't mean that its object is no longer used. That's the whole reason we garbage collection in the first place, so the programmer no longer needs to worry about what references what. For example, in the following code, variable :a goes out of scope, but the array it is attached to is returned as the value of the function. Finalizing :a at the end of returning would be a bad idea. def returning a = ["var a"] end array = returning p array # => ["var a"] Even if you could account for return values, and values being squirreled away inside of other structures, sometimes its hard to determine when a variable actually goes out of scope. For example ... def closing b = ["var b"] [ proc { b }, proc{|v| b = v} ] end get, set = closing p get.call #=> ["var b"] set.call(10) p get.call #=> 10 The scope containing variable :b is captured by the closures returned from 'closing'. Later in the main program, the get closure is called and we see that the value for b is ["var b"]. Then we call the set closure and change the binding for variable b. Now the get closure returns the new binding. So a scope can continue to live, even after the method defining the scope has exited. This is just weird to people brought up in the Pascal/C/Algol like languages. One final example of scope weirdness. You could argue that we could detect when closures are created and handle that as a special case, since closures have to be created right there in the scope. However, there is another time when scope is captured, and it doesn't have to happen in the lexical scope of the function. def continuing c = ["var c"] cc = silly puts "C = #{c}" cc end def silly callcc {|cc| cc} end cvar = continuing # => C = ["var c"] cvar.call(proc{}) # => C = ["var c"] Here method 'continuing' returns the value of 'silly', after printing the value of variable :c. Silly actually returns a continuation object, although there is no way to know that from examining the text of 'continuing'. Outside, in the main program, we call the continuation, which restarts the 'continuing' method at the point silly was called and prints the value of variable :c again. All these things put together make it difficult to do a finalization when a function exits. Ain't dynamic languages wonderful :-) -- -- Jim Weirich jweirich@one.net http://jimweirich.umlcoop.net --------------------------------------------------------------------- "Beware of bugs in the above code; I have only proved it correct, not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)