Hi everybody, 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++)
On 7/24/07, Marcin Tyman <m.ty...@interia.pl> wrote:
> Hi everybody, > 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++)
There are three kinds of variables in Ruby local @@class_var @instance_var
My tip, do not use @@class_var, use @inst_var on the correct level
Here goes the classic example of a "static" (forget this expression;) variable counting instances. I will use an instance variable of the class (commonly called class instance variables) for that
549/49 > cat class-inst.rb && ruby class-inst.rb
class A @count = 0 class << self attr_accessor :count end def initialize val @a = val self.class.count += 1 end end
a=A.new 42 b=A.new 43
p a p b p A.count #<A:0xb7db6764 @a=42> #<A:0xb7db66b0 @a=43> 2 HTH Robert
-- I always knew that one day Smalltalk would replace Java. I just didn't know it would be called Ruby -- Kent Beck
> Hi everybody, > 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++)
If you mean static variables that are visible in a single method only, then no, there is no way to do it. You should probably rethink your design if it relies on such archaic features of other programming languages. :-)
On Tue, 24 Jul 2007, Jeremy Henty wrote: > On 2007-07-24, Robert Klemme <shortcut...@googlemail.com> wrote:
>> If you mean static variables that are visible in a single method >> only, then no, there is no way to do it.
> *cough*
> class Foo > count = 0 > define_method(:foo) { count += 1 } > end > x = Foo.new > 3.times { puts x.foo }
> ==> > 1 > 2 > 3
"Static" is a misleading term, though. It's just a local variable that happens to get wrapped in a closure. In general, I don't think Ruby and the word "static" mix very well :-) Constants are sort of statically scoped, but that's about it.
On 2007-07-24, dbl...@wobblini.net <dbl...@wobblini.net> wrote:
> On Tue, 24 Jul 2007, Jeremy Henty wrote:
>> On 2007-07-24, Robert Klemme <shortcut...@googlemail.com> wrote:
>>> If you mean static variables that are visible in a single method >>> only, then no, there is no way to do it.
>> class Foo >> count = 0 >> define_method(:foo) { count += 1 } >> end
> "Static" is a misleading term, though. It's just a local variable > that happens to get wrapped in a closure.
True, but it is still "visible in a single method only", which AIUI Robert Klemme claimed was undoable. Even though Ruby doesn't have truely static variables, it can create something that behaves very like (a common use case of) them. That's all I'm claiming.
Am Dienstag, 24. Jul 2007, 18:03:15 +0900 schrieb Robert Dober:
> On 7/24/07, Marcin Tyman <m.ty...@interia.pl> wrote: > >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++) > There are three kinds of variables in Ruby > local > @@class_var > @instance_var
Further
$global
which I use almost never (except $1, $> etc.).
> My tip, do not use @@class_var, use @inst_var on the correct level
> class A > @count = 0 > class << self > attr_accessor :count > end > end
> Am Dienstag, 24. Jul 2007, 18:03:15 +0900 schrieb Robert Dober: > > On 7/24/07, Marcin Tyman <m.ty...@interia.pl> wrote: > > >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++) > > There are three kinds of variables in Ruby > > local > > @@class_var > > @instance_var
> Further
> $global
LOL completely forgot them, thx.
> which I use almost never (except $1, $> etc.).
exactly <snip> Robert
-- I always knew that one day Smalltalk would replace Java. I just didn't know it would be called Ruby -- Kent Beck
On 2007-07-24, Robert Dober <robert.do...@gmail.com> wrote:
> On 7/24/07, Jeremy Henty <onepo...@starurchin.org> wrote:
>> class Foo >> count = 0 >> define_method(:foo) { count += 1 } >> end
> Terribly slow BTW :(
Why is that? Are all methods created by define_method slow? Or is it something particular to the way I'm using it here? I'm really getting into metaprogramming with define_method so I'd like to learn about the pitfalls.
> On 2007-07-24, Robert Dober <robert.do...@gmail.com> wrote: > > On 7/24/07, Jeremy Henty <onepo...@starurchin.org> wrote:
> >> class Foo > >> count = 0 > >> define_method(:foo) { count += 1 } > >> end
> > Terribly slow BTW :(
> Why is that? Are all methods created by define_method slow? Or is it > something particular to the way I'm using it here? I'm really getting > into metaprogramming with define_method so I'd like to learn about the > pitfalls.
> Regards,
> Jeremy Henty
I believe Robert developed a library for using closure based properties a short while back. Something to do with a breed of dog or something :) Cool stuff. But he found it to be slow if I remember correctly.
> On 2007-07-24, Robert Dober <robert.do...@gmail.com> wrote: > > On 7/24/07, Jeremy Henty <onepo...@starurchin.org> wrote:
> >> class Foo > >> count = 0 > >> define_method(:foo) { count += 1 } > >> end
> > Terribly slow BTW :(
> Why is that? Are all methods created by define_method slow? Or is it > something particular to the way I'm using it here? I'm really getting > into metaprogramming with define_method so I'd like to learn about the > pitfalls.
> Regards,
> Jeremy Henty
No it is the lookup, if you are interested I can send you my benchmarks, without any twists it was 4 to 5 times slower than ivar lookup and with twists like read_only, write_once, rw_locks it quickly climbed to a factor worse than 10 :( Robert
-- I always knew that one day Smalltalk would replace Java. I just didn't know it would be called Ruby -- Kent Beck
> On 7/24/07, Jeremy Henty <onepo...@starurchin.org> wrote: > > On 2007-07-24, Robert Dober <robert.do...@gmail.com> wrote: > > > On 7/24/07, Jeremy Henty <onepo...@starurchin.org> wrote:
> > Why is that? Are all methods created by define_method slow? Or is it > > something particular to the way I'm using it here? I'm really getting > > into metaprogramming with define_method so I'd like to learn about the > > pitfalls.
> > Regards,
> > Jeremy Henty
> I believe Robert developed a library for using closure based > properties a short while back. Something to do with a breed of dog or > something :) Cool stuff. But he found it to be slow if I remember > correctly.
Thx, properties are broken, but thx anyway :)
> Todd
-- I always knew that one day Smalltalk would replace Java. I just didn't know it would be called Ruby -- Kent Beck
> On 2007-07-24, dbl...@wobblini.net <dbl...@wobblini.net> wrote:
> > On Tue, 24 Jul 2007, Jeremy Henty wrote:
> >> On 2007-07-24, Robert Klemme <shortcut...@googlemail.com> wrote:
> >>> If you mean static variables that are visible in a single method > >>> only, then no, there is no way to do it.
> >> class Foo > >> count = 0 > >> define_method(:foo) { count += 1 } > >> end
> > "Static" is a misleading term, though. It's just a local variable > > that happens to get wrapped in a closure.
> True, but it is still "visible in a single method only", which AIUI > Robert Klemme claimed was undoable. Even though Ruby doesn't have > truely static variables, it can create something that behaves very > like (a common use case of) them. That's all I'm claiming.
Well, in Ruby there is usually a workaround. But there is no real built in static method variables feature. So we're both correct in a way. :-)
Also, I did not want to encourage people to use this pattern because I believe it's not good. Here's why: if you have a design complex enough make separation of your instance state by method necessary then you should break up functionality into more classes to keep it manageable.
On 2007-07-24, Robert Klemme <shortcut...@googlemail.com> wrote:
> ... if you have a design complex enough make separation of your > instance state by method necessary then you should break up > functionality into more classes to keep it manageable.
Fair enough. In fact that often happens to me; I implement something in a clever way at first, then when it's time to clean up and refactor I see that I was being *too* clever and rewrite it much more straightforwardly. I guess that means I'm clever, but meta-stupid (for being too clever), but meta-meta-clever (for noticing when I'm being meta-stupid). I think I'll quit there while I'm ahead! :-)
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.
> 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
> > 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++)
> On 7/24/07, Joel VanderWerf <vj...@path.berkeley.edu> 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++)
> 2007/7/25, Robert Dober <robert.do...@gmail.com>: > > On 7/24/07, Joel VanderWerf <vj...@path.berkeley.edu> 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++)
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.
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
On Wed, 25 Jul 2007, Robert Dober wrote: > On 7/24/07, Joel VanderWerf <vj...@path.berkeley.edu> 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++)
> > On 7/24/07, Joel VanderWerf <vj...@path.berkeley.edu> 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++)
> I get the same result with or without the line between the two times > calls. Are you seeing it output 42?
No that is the pleasant surprise :) If I understood the Guru Sans correctly that is because the interpreter defines (0..0) scope locally -- the same object_id notwithstanding -- amazing feature indeed. Needless to say that one should rather not use it ;)