From: Robert Dober Date: 2007-07-25T18:17:13+09:00 Subject: Re: Static variables in Ruby. On 7/25/07, Robert Klemme wrote: > 2007/7/25, Robert Dober : > > On 7/24/07, Joel VanderWerf wrote: > > > Nobuyoshi Nakada wrote: > > > > Hi, > > > > > > > > At Tue, 24 Jul 2007 17:40:57 +0900, > > > > Marcin Tyman wrote in [ruby-talk:261483]: > > > >> Is any way to define static variables over function? As class static > > > >> variables there is possible to define a static class variable as > > > >> @@name_of_var. But I'm not sure if Ruby let define such variables in > > > >> functions (like in C/C++) > > > > > > > > def foo(x) > > > > (0..0).instance_eval{x,@x = @x,x} > > > > x > > > > end > > > > 3.times{|i|p foo(i)} #=> nil, 1, 2 > > > > > > > > The literal object can be Float, Regexp or Bignum, but Range > > > > would be faster a bit. > > > > > > > > > > Interesting. That is because Float, Regexp, and Bignum are instantiated > > > per scope, right? > > > > > > Sometimes a little abstraction leakage can be useful! > > > > > > -- > > > vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407 > > > > > > > > I did not believe this,and why should I? > > But it seems to be true ;) > > def foo(x) > > (0..0).instance_eval{x,@x = @x,x} > > x > > end > > > > 3.times{ |i| puts foo(i) } > > (0..0).instance_eval{@x=42} > > 3.times{ |i| puts foo(i) } > > > > Run this for a pleasant surprise :) > > The reason why it works is this: > > >> def f; (0..0).object_id end > => nil > >> 5.times {p f} > 69868270 > 69868270 > 69868270 > 69868270 > 69868270 > => 5 Actually this is a reason why it should *not* work def f; (0..0).object_id end 2.times{ p f } p (0..0).object_id Nevertheless it does because of the scope local optimization if I understood Jo�l correctly. > > The Ruby interpreter optimizes this when both ends are constant. > > >> def g(a)(0..a).object_id end > => nil > >> 5.times {p g(1)} > 69627090 > 69626930 > 69626820 > 69626680 > 69626560 > => 5 > > Kind regards > > robert > > Hmm as we are exploring it, let us see if it works for all constants, somehow I doubt it... Fixnum ranges work, Bignum ranges do not 646/146 > cat rang_oid.rb && ruby rang_oid.rb #!/usr/local/bin/ruby # vim: sw=2 sts=2 ft=ruby expandtab tw=0: def f; "08%x" % (1..1073741823).object_id end def b; "08%x" % (1..1073741824).object_id end puts "f" 3.times{ puts f } puts "b" 3.times{ puts b } f 08..fdbeb46ae 08..fdbeb46ae 08..fdbeb46ae b 08..fdbeb4366 08..fdbeb4334 08..fdbeb4302 So for bignums the values will not be kept. Robert -- I always knew that one day Smalltalk would replace Java. I just didn't know it would be called Ruby -- Kent Beck