I'm trying to understand classes and objects. The Pick axe book points out
the "once" method in class Date and how it is defined using the object
singleton technique of "class << self". Actually Date uses this in several
places. Up until seeing Date I thought the reason for this idiom was to
add/replace methods in classes *when you don't have convenient access to the
class definition* -- basically, use this when it's not your class you need
to enhance. But the fact that Date uses it several times indicates there is
another reason to use it.
Here are some examples from Date:
class << self; alias_method :leap?, :gregorian_leap? end
class << self; alias_method :new0, :new end
I just noticed that every use of class << self in Date contains an
alias_method.
I'm trying to understand classes and objects. The Pick axe book
points out the "once" method in class Date and how it is defined
using the object singleton technique of "class << self". Actually
Date uses this in several places. Up until seeing Date I thought the
reason for this idiom was to add/replace methods in classes *when you
don't have convenient access to the class definition* -- basically,
use this when it's not your class you need to enhance. But the fact
that Date uses it several times indicates there is another reason to
use it.
As you guessed the reasons are different: typically you use "class
<<something...end" if you have to define several methods or if you need a
class context for things to work (for example "alias").
These are equivalent:
class Foo
class <<self
def m1() "foo" end
end
class <<Foo
def m2() "foo" end
end
def self.m3() "foo" end
def Foo.m4() "foo" end
end
class <<Foo
def m5() "foo" end
end
def Foo.m6() "foo" end
x = Foo
def x.m7() "foo" end
class <<x
def m8() "foo" end
end
Now you have methods m1 to m8 as instance methods of Foo. You can do
Foo.m1(), Foo.m2 etc.
More technically, with class <<something ... end you make definition for
the so called "singleton class" the class instance responsible for the
single instance at hand (which happens to be a class object in this case;
but you can repeat the example above with any object instead of Foo). You
cannot create instances from this class:
irb(main):001:0> class Foo
irb(main):002:1> p new
irb(main):003:1> end
#<Foo:0x10192d58>
=> nil
irb(main):004:0> class <<Foo
irb(main):005:1> p new
irb(main):006:1> end
TypeError: can't create instance of virtual class
from (irb):5:in `new'
from (irb):5
Here are some examples from Date:
class << self; alias_method :leap?, :gregorian_leap? end
class << self; alias_method :new0, :new end
I just noticed that every use of class << self in Date contains an
alias_method.