From: ara.t.howard@... Date: 2007-03-25T01:16:02+09:00 Subject: Re: scope and RAII On Sat, 24 Mar 2007 jeff_alexander_44@yahoo.com wrote: > > def scope(*args) > yield(*args) > end > > scope(Array.new) { |array| > array.push 1 > array.push 7 > array.push 11 > puts array.join(",") > } > # here the variable 'array' is gone -- is it deallocated? array is merely a label - a handle. the variable is references, the one created by Array.new still exists. you can prove this to yourself harp:~ > cat a.rb def scope(*args) yield(*args) end scope(Array.new) { |array| array.push 1 array.push 7 array.push 11 puts array.join(",") } ObjectSpace.each_object(Array){|obj| p obj} harp:~ > ruby a.rb 1,7,11 [[1, 7, 11]] [1, 7, 11] [] [] [] [] ["/home/ahoward//lib/ruby/site_ruby/1.8", "/home/ahoward//lib/ruby/site_ruby/1.8/i686-linux", "/home/ahoward//lib/ruby/site_ruby", "/home/ahoward//lib/ruby/1.8", "/home/ahoward//lib/ruby/1.8/i686-linux", "."] [:utime, :stime, :cutime, :cstime] in fact, your scoping method has managed to create three of them ;-) one here scope(Array.new) ^^^^^^^^^ one here def scope(*args) ^^^^ and one here yield(*args) ^^^^ so this probably isn't the best way to conserve on resource utilization! ;-) > > I am interested in using ruby for some resource-intensive tasks. In > the above example, imagine Array replaced with some resource-tied > class written in C, for example a set of hardware textures. > > Does ruby make a special effort to release a variable when it goes out > of scope? The canonical example is > > File.open("foo.txt") { |f| > print f.read > } > # internal file handle released here > > Is this behavior a general rule, or just a special case for > File.open()? And is it released immediately or upon the > next GC pass? there are two issues here - the fd, which __is__ released at the end of the block - any ruby variables, which will only be freed by the GC in the case of the first the only reason it's freed is because it's coded to do exactly that, you can imagine it like class File def open path, mode, &b fd = open_file path, mode b.call fd ensure fd.close end end this is the general pattern you use to force resource deallocation. note that it's your responsiblity and that ruby does nothing special to make sure it happens. -a -- be kind whenever possible... it is always possible. - the dalai lama