hello, rails has a lot of code like this class A class << self def method ... end end end could someone explain why subclassing "self" is needed here? how is it different from just defininf methods inside class A? thanks konstantin
Hello, rails has a lot of code like this: class A class << self def method ... end end end could someone explain why subclassing of self is needed here? why defining methods in class A itself is not enough? thanks konstantin
On Oct 12, 2005, at 2:18 PM, akonsu wrote:> hello, > > rails has a lot of code like this > > class A > class << self > def method > ... > end > end > end > > could someone explain why subclassing "self" is needed here? how is it > different from just defininf methods inside class A?Note that the << operator is not the < operator. What happening is not subclassing (the < operator), but reopening. The "eigenclass" or "singleton class" of A is being reopened, and methods being added to it. Note that all three of the following have identical semantics: class A def A.method ... end def self.method ... end class << self def method ... end end end The bottom line is that the class << self idiom is frequently used to specify a series of "class methods", as opposed to "instance methods". - Jamis
hello, thank you for your response. this looks like a very vague feature to me. and i am still trying to understand it. 1) the ruby documentation says that "class << var" makes the instance variable "var" change its type (class) from whatever it had before to a new anonymous class. this class will only be effective as long as "var" exists. is this so? 2) in addition this expression returns value of its body. so we can write: c = class << var; x; end and get "x" as the value of "c" if "class << var" contains a bunch of "def"s, the value returned is nil. so i do not understand how the class being defined uses the method definitions found inside "class << self" given that the value returned from the "reopening" expression is nil. in addition, if my item 1) is correct, how does reassigning a class for "self" works inside the class definition? also, could you explain what you mean by "reopening"? i would appreciate a very technical explanation, on the level of interpreter. what exactly happens when the interpreter encounters this expression? konstantin> > > > Note that the << operator is not the < operator. What happening is > not subclassing (the < operator), but reopening. The "eigenclass" or > "singleton class" of A is being reopened, and methods being added to > it. Note that all three of the following have identical semantics: > > class A > def A.method > ... > end > > def self.method > ... > end > > class << self > def method > ... > end > end > end > > The bottom line is that the class << self idiom is frequently used to > specify a series of "class methods", as opposed to "instance methods". >
On 10/13/05, akonsu <akonsu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> hello, > > thank you for your response. this looks like a very vague feature to > me. and i am still trying to understand it. > > 1) the ruby documentation says that "class << var" makes the instance > variable "var" change its type (class) from whatever it had before to > a new anonymous class. this class will only be effective as long as > "var" exists. is this so?No, it changes ''self'' to an anonymous class that is the immediate superclass of var (var''s "eigenclass") - the inheritance chain looks like var---[class << var]---[var.class] Now when you say class A; ....; end, the class/end block opens up a scope in which ''self'' is the class A. any def/end block will add an *instance* method to the class A; i.e., a method that is added to all instances of class A. Now, supposing you have the following class A # self = A class << self # self = A''s eigenclass def foo # method ''foo'' is an instance method of A''s eigenclass end end end But the only instance of an object''s eigenclass is the object itself. So here, method foo is added to the *object* A, and can therefore loosely be thought of as a ''class method''. What is going on is that classes in Ruby are just objects of class Class, and the class name, e.g. String, Array etc, is a constant (remember that variables beginning with a capital letter are constants in ruby) referring to that object. So A''s inheritance chain looks like A ---- [ class << A ] ---- [Class] and when you add an instance method to A''s eigenclass, it is only accessible by sending a message to the class object itself, thus A.foo "Reopening", incidentally, refers to the fact that multiple class Bar/end blocks are cumulative, thus you can say class A def method1 end end class A def method2 end end a = A.new a.methods #=> ["method1", "method2"] So when we say class << self, we are reopening A''s eigenclass (remember, within a def method/end block, self refers to the object that will be created, but within a class/end block and outside any method def, self refers to the class object itself) and adding methods that can be called via A.method. You can also use reopening to extend any class, including the built in classes: class String def answer 42 end end "hello world".answer #=> 42 martin