From: Joel VanderWerf Date: 2005-01-18T15:24:39+09:00 Subject: Re: Fwd: [suby-ruby] Your all time desired fundemental Ruby mod Martin DeMello wrote: > gabriele renzi wrote: > >>Martin DeMello ha scritto: >> >>>I can think of at least one good us for the current @@ variables - >>>subclassable GUI components that inherit hierarchy-shared look-and-feel >>>properties from the parent class. What would be the elegant way to do >>>this if @@ variables go per-class? >> >>constants? > > > Constants aren't modifiable at run time (well, you aren't supposed to > modify them). I was thinking of a scheme whereby you could simply modify > the current theme and have all subclassed widgets pick up on that. A > shared access method to an entirely separate Theme object might do it, > but I still think @@variables are the elegant solution in this case. One limitation of @@var for this purpose is that a subclass cannot decide that it wants to override the base class's binding--if you assign to @@var in a subclass, you affect every class that inherits from the base. Another problem with @@var is that the order of initialization affects how many bindings exist: === two-bindings.rb === class A end class B < A @@v = 1 end class A @@v = 2 end class A puts @@v # ==> 2 end class B puts @@v # ==> 1 end ====================== === one-binding.rb === class A @@v = 2 end class B < A @@v = 1 end class A puts @@v # ==> 1 end class B puts @@v # ==> 1 end ====================== So class vars have these problems, constants are not mutable, and class instance vars do not inherit. That's where superhash (on RAA) might help. It can be used to set up hashes that inherit along the class hierarchy (or other structure, such as a tree or dag). Internally, it uses class instance variables. A really trivial example: === superhash-example.rb === require 'superhash' class A class_superhash :options options[:foo] = "A foo" options[:bar] = "A bar" def options; self.class.options; end end class B < A options[:foo] = "B foo" end p A.options p B.options.to_hash p B.new.options.to_hash __END__ output: {:foo=>"A foo", :bar=>"A bar"} {:foo=>"B foo", :bar=>"A bar"} {:foo=>"B foo", :bar=>"A bar"} ==================================== So B can inherit and optionally override attributes from A, and the granularity is per key in the hash.