From: dblack@... Date: 2005-12-12T05:19:59+09:00 Subject: Re: About class methods Hi -- On Sun, 11 Dec 2005, jonathan wrote: > dblack wrote: >> >> The singleton class mechanism is just a way to store those "extra" >> methods. The methods written for a (namely, "x") go in a's singleton >> class; those for b, in b's; etc. These classes are created >> automatically when they are needed. > > Hmm. Ok, so there really is no singleton class for Myclass? In other > words, must the singleton always be associated with an instance and not > a class? Every object (almost) can have a singleton class, including Class objects. >> >> If you want to open a class definition block for an object's singleton >> class, you use the class keyword, plus "<< obj". This special syntax >> is necessary because singleton classes are anonymous. Other than >> that, it's very much like doing "class C". >> >> It's all very simple and elegant, isn't it? :-) >> > > Yea. That is cool, but can you still do something like this: > > class Myclass > end > > def extend_class( some_class ) > code = %{ class #{some_class.class}_extension < #{some_class.class} > def new_method1 > end > ... > end } > eval( code ) > > extend_class( Myclass ) > x = Myclass_extension.new > x.new_method1 > y = Myclass_extension.new > y.new_method1 > > Some variation of this (where the extended class is named uniquely) > should allow infinitely many extended subclasses and also allow > non-singleton (i.e., many) instances of the subclasses. There are easier ways, such as (I think someone else pointed out) Class.new(superclass). Using eval is a stretch; in fact, I'm fairly confident in saying that it's almost a certain sign that you're doing something which can be done a cleaner way, or that perhaps needs to be rethought entirely. Anyway -- a non-eval version of what you've got above might be something like: class MyClass end def extend_class(classname) ex = Object.const_set(classname.to_s + "_extension", Class.new) ex.class_eval do def new_method1 puts "new method" end end end extend_class(MyClass) x = MyClass_extension.new x.new_method1 > Of course, I suppose you could start with x and y as instances of the > base class and add the new_method's to each of them just as easily (and > with probably less typing). So, would there ever be a reason to do > something like I wrote above? Probably not :-) But it's good to learn all of these permutations, I think. David -- David A. Black dblack@wobblini.net "Ruby for Rails", forthcoming from Manning Publications, April 2006!