Classes and constants magic
An anonymous class!
bear = Class.new puts bear # => #<Class:0x8ef08> puts bear.class # => Class puts bear.name # => ""
This class has no name, it's anonymous. Let's create an instance of the anonymous class.
b = bear.new puts b.class #=> #<Class:0x8ef08>
b.class would return the class name. Anonymous means no name. Ruby returns an instance of class (the one created with
A class name is always a constant. The call
class Foo; end tells Ruby to create an instance of
Class and assign that instance to the constant
Foo. These two calls are equal:
class Foo; end Foo = Class.new
Let's try this with our anonymous class. We're assigning the instance of
Class stored in the variable
bear to a constant,
Bear = bear puts b.class # => Bear puts b.name # => "Bear"
It now reports
Bear as the class name, because it's no longer anonymous.
Our instance of
Class seems to have vanished, but it's still possible to access this instance directly.
class << Bear puts self # => #<Class:Bear> end
It couldn't hide from us after all. The special (
class <<) syntax lets us access it. It also says
Bear rather than
0x8ef08, to let us know that this class is no longer anonymous.
This secret and hidden instance of
Class is what rubyists refers to as the _metaclass_ of a class.
#<Class:Bear> is the metaclass of
It's this metaclass that holds all the class methods. That makes sense, because a constant can't have methods. Instances is the only thing in Ruby that has methods.
Important summary: Class methods of a class are simply instance methods of its metaclass. Read this out loud 10 times.
Code speaks louder than words
Bear.class_eval do def say_hello puts "Hello!" end end Bear.say_hello # => NoMethodError: undefined method ‘say_hello’ for Bear:Class
We need to define the method on the metaclass, the instance of
class << Bear def say_hello puts "Hello!" end end Bear.say_hello # => "Hello!"
_why the lucky stiff has more on the subject.
Questions or comments?