I'm working on this tutorial here:
http://rubymonk.com/learning/books/4-ruby-primer-ascent/chapters/39-ruby-s-object-model/lessons/131-singleton-methods-and-metaclasses
The lesson is on classes/metaclasses, but they are using a syntax that I'm not familiar with. Please see the use of << below
class Object
def metaclass
class << self
self
end
end
end
a=Object.new
p a.metaclass.new
I know def metaclass is a method, but what is meant by class << self? It has a corresponding end block, but I'm still very unclear what this is exactly doing
(Note: The point of the above exercise is just showing that you cannot instantiate a metaclass -- which I understand, I'm just having trouble wrapping my head around that << operator in this context.
Thanks!
class << self opens up self's singleton class, so that methods can be redefined for the current self object.
Let's look at a particular example:
s = String.new("abc")
s.metaclass
=> "#<Class:#<String:0x0000010117e5d8>>"
Let's have a closer look at what happens here:
Inside the definition of metaclass, self refers to the current instance, in this example the string "abc".
class << self in this example is equivalent to class << "abc" which opens up the singleton-class of that given instance , in this case String "abc".
It then returns self inside the opened-up class of the current instance -- the opened-up class is in the example the class String.
In general, the definition of metaclass opens up the class definition of the class of the given instance/object, and then returns that class name.
A more detailed look at 'self' can be found in Yehuda Katz's article "Metaprogramming in Ruby: It’s All About the Self".
I also recommend the screen-cast series by the Pragmatic Programmers on The Ruby Object Model and Metaprogramming.
Related
2 main techniques for creating class methods (without the obvious "def self.method") are:
Defining them in "class << self" block
Defining ClassMethod module and extending it later
I personally prefer second way, seems cleaner. Does anyone has any reason to prefer one technique over the other?
There's also "class_method" method, but I never used it, it has quite complex implementation and seem to do a lot more than previous 2.
self.method is the simplest option when you just need to create one method without dependencies or related logic.
class << self allows you to do far more than define methods on the metaclass. This is useful when you're defining methods which need to work with other parts of the metaclass (eg. aliasing existing method names).
For instance:
class Logger
class << self
attr_reader :payload
def log(message)
#payload = message
end
end
end
The module extension method comes in handy for method reuse and to group multiple coherent methods.
For instance:
module QueryMethods
def find
end
def where
end
end
module FactoryMethods
def build
end
def create
end
end
class BusinessModel
extend QueryMethods
extend FactoryMethods
end
First, the class << foo syntax opens up foo's singleton class (eigenclass). This allows you to specialise the behaviour of methods called on that specific object.
a = 'foo'
class << a
def inspect
'"bar"'
end
end
a.inspect # => "bar"
a = 'foo' # new object, new singleton class
a.inspect # => "foo"
class << self opens up self's singleton class, so that methods can be redefined for the current self object (which inside a class or module body is the class or module itself). Usually, this is used to define class/module ("static") methods
class << self is good at keeping all of your class methods in the same block. If methods are being added in def self.method from then there's no guarantee (other than convention and wishful thinking) that there won't be an extra class method tucked away later in the file.
def self.method is good at explicitly stating that a method is a class method, whereas with class << self you have to go and find the container yourself.
Which of these is more important to you is a subjective decision, and also depends on things like how many other people are working on the code and what their preferences are.
Pros of “class << self” style
I'm going through the Ruby Koans Ruby Koans and I'm at a place in "about_class_methods.rb" where there is a discussion of setting up class methods, and the Koans talk about three ways.
The two major ways to write class methods are:
1:
class Demo (define/open class)
def self.method
end
2:
class << self
def class_methods
end
end
The koans also talk about a third method, I've never seen (that I remember):
def Demo.class_method_third_way
end
Q1 This third way is actually clearer to me than any other. Is there a reason I don't understand about why no one uses it?
Q2 Why am I wrong in thinking the syntax for 2 should be "self << def name end"? That is "Why is the syntax the way it is?" Does the class Object hold a reference to all Classes and this sticks in the method for the self class?
As always, thanks for your help and patience!
In (early) development classes get renamed as insight grows (not Person but Employee, not Job but one or more Roles etc.) This renaming is prone to errors if the class name is hardcoded in the class itself.
In class body, self refers exactly the class object being defined. That's why def self.some_method works the same as def Demo.some_method.
class Demo
puts self.object_id == Demo.object_id
end
#=> true
class << some_obj is the syntax to access the singleton class of some_obj. Refer to the Ruby doc:
The singleton class (also known as the metaclass or eigenclass) of an object is a class that holds methods for only that instance. You can access the singleton class of an object using class << object ... Most frequently you’ll see the singleton class accessed like this:
class C
class << self
# ...
end
# or
class << C
end
end
I'm having a trouble figuring out how to access a variable in a class << self from another class. I've searched and found many questions close to this but not exactly:
class << self
##var="foo"
end
class A
puts ##var
end
I've even tried creating class A within class << self with no luck either.
How can I access ##var?
You can do this:
class << self
##var="foo"
end
self.class.class_variable_get :##var
But I'm really skeptical that you actually need to use a class variable in a singleton class. It seems complicated. Maybe you could ask another question explaining what you're really trying to do.
I can't seem to grasp the exact difference between these two "constructs". To my mind, the following small script should output the same thing three times:
class Example
puts self
class << self
puts self
end
instance_eval do
puts self
end
end
However, the output is:
Example
#<Class:Example>
Example
Here's my rationale:
Example is an instance of Class, so self in the class body refers to that;
class << obj sets self to whatever obj is in the given block, which in my case is the instance of Class that is Example (this is where I'm probably wrong);
instance_eval runs the block in the given instance, so, in my case it's pretty much the same as putting the code in the block directly in the class body.
My current guess is that class << self inserts a ghost class between Example and Class and sets self to that, but the output of #<Class:Example> is not confirming that at all.
So what is wrong with my rationale?
class << obj sets self to whatever obj is in the given block, which in my case is the instance of Class that is Example (this is where I'm probably wrong);
No, class << obj opens up the singleton class of obj. As you correctly pointed out, inside of a class declaration, self refers to the class itself, so, in this case, the "inner" self (i.e. the one being passed to puts) refers to the singleton class of Example.
In my opinion, class << self has been one of the most obnoxious bits of syntax in Ruby. People new to the language have little idea what it means, apart from cargo-cult conventions, and even those intimately familiar with the language have only a hazy understanding of what differentiates it from instance_method, as the two do seem to be remarkably similar.
Here's an example of two different ways of defining a class method:
class Example
class << self
def class_def
:class_def
end
end
instance_eval do
def instance_def
:instance_def
end
end
end
You can check that these work by calling the methods:
puts Example.class_def.inspect
# => :class_def
puts Example.instance_def.inspect
# => :instance_def
The difference is when you're dynamically creating methods using define_method since the binding does appear to be incorrect on the instance_eval version:
class Example
class << self
define_method(:class_def) do
:class_def
end
end
instance_eval do
define_method(:instance_def) do
:instance_def
end
end
end
This results in the instance_def method being defined, but not being bound to the class itself:
puts Example.class_def.inspect
# => :class_def
puts Example.instance_def.inspect
# => NoMethodError: undefined method ‘instance_def’ for Example:Class
The only reliable way to create dynamic methods is with class << self. The method instance_def appears to be created and discarded as it doesn't show up in Example.methods even inside that block.
In Ruby, we could use super within singleton method to call the corresponding super class's singleton method, like the following code shows.
class Base
def self.class_method
puts "Base class method"
end
end
class Derived < Base
def self.class_method
puts "Derived class method"
super
end
end
Derived.class_method
# Derived class method
# Base class method
However, I don't seem quite get how that call to super within Derived.class_method could reach Base.class_method. I'd assume that class_method is defined on their metaclass, does that mean their metaclass has parent/child relationship? (I can't quite confirm that by experiments)
Update: I'm asking this question because I remembered seeing somewhere there's some kind of relationship bettwen base and derived class' metaclass (but I can't find it any more). In addition to know how actually super works, I'd also like to confirm whether the two metaclasses are totally separate or not.
There are four class objects in play here:
<Class>---class---><Class>
Base #Base
^ ^
| |
| |
super super
| |
| |
<Class> <Class>
Derived---class--->#Derived
Nomenclature:
<...> is the class of each object.
The name of the class is on the second line.
If the name starts with #, it's the eigenclass (aka singleton class).
super points to a class's superclass
class points to the class's class.
When you call Derived.class_method, Ruby follows the "right one and then up" rule: First go to the object's class, then follow the superclass chain up, stopping when the method is found:
The receiver of the "class_method" call is Derived. So follow the chain right to Derived's class object, which is its eigenclass (#Derived).
Derived does not define the method, so Ruby follows the chain up the chain to #Derived's superclass, which is #Base.
The method is found there, so Ruby dispatches the message to #Base.class_method
You don't think I knew all this stuff off the top of my head, did you? Here's where my brain got all this meta juju: Metaprogramming Ruby.
Part 2. How to make an "eigenclass" (aka "singleton class") come out of hiding
class Object
def eigenclass
class << self
self
end
end
end
This method will return the eigenclass of any object. Now, what about classes? Those are objects, too.
p Derived.eigenclass # => #<Class:Derived>
p Derived.eigenclass.superclass # => #<Class:Base>
p Base.eigenclass # => #<Class:Base>
Note: Above is from Ruby1.9. When run under Ruby 1.8, you get a surprise:
p Derived.eigenclass.superclass # => #<Class:Class>
To clarify and correct what i wrote in the comments regarding the way Ruby hides/exposes eigenclasses, here is the situation:
Ruby 1.8:
(1) The Object#class method always returns the first real (non eigenclass or iclass) superclass of the actual class of an object.
e.g
o = Object.new
class << o; end
o.class #=> returns Object, even though the _actual_ class is the eigenclass of o
In other words, the Object#class method will never return an eigenclass, it passes over them
and instead returns the first 'real' class it finds in the inheritance hierarchy.
(2) The Class#superclass method has two cases. If the receiver is not an eigenclass then it simply returns the superclass. However, if the receiver is an eigenclass then this method returns the actual (i.e not necessarily real) class of the receiver.
# case where receiver is a normal class (i.e not an eigenclass)
Module.superclass #=> Object (behaves as expected)
# case where receiver is an eigenclass
class << Module; superclass; end #=> returns Class, this is NOT the superclass
From above, Class#superclass behaves as expected in the case of a normal class, but for the eigenclass example it states the superclass of the eigenclass of Module is Class which is not true. From this diagram http://banisterfiend.wordpress.com/2008/10/25/the-secret-life-of-singletons/ we know that the superclass of the eigenclass of Module is actually the eigenclass of Object. I am unsure why Ruby 1.8 has this strange behaviour.
Ruby 1.9:
(1) The Object#class method behaves identically to the 1.8 version.
(2) The Class#superclass method no longer has two cases, it now treats eigenclasses the same way it treats normal classes and returns the actual superclass as expected.
e.g
class << Module; superclass; end #=> #<Class:Object>
This diagram explains the relationship: http://banisterfiend.wordpress.com/2008/11/25/a-complete-ruby-class-diagram/
Also, here are some other posts that explain more the intricacies of eigenclasses:
http://www.klankboomklang.com/2007/10/05/the-metaclass/
http://www.klankboomklang.com/2007/09/21/the-singleton-class/
And here's a fairly hard-going one that explains more than you'd probably like to know:
http://banisterfiend.wordpress.com/2008/10/25/the-secret-life-of-singletons/