How is this explained? Can I replace self with some other object?
views:
115answers:
4This syntax is used in ruby to access an object's metaclass, or singleton class. The metaclass is used to store methods for an individual object.
obj = # whatever...
class <<obj
# here, self is defined as obj's metaclass
# so foo will be an instance method of obj's metaclass
# meaning that we can call obj.foo
def foo
# ...
end
end
# this is equivalent to the above
def obj.foo
# ...
end
This is a core part of the language, and isn't defined in any library.
You use that syntax to add class methods, which you call on the class, instead of on a particular instance of that class.
For example:
class Foo
class << self
def do_foo
# something useful
end
end
end
Now you can call Foo.do_foo even if you don't have an object of type Foo.
This is equivalent:
class Foo
def self.do_foo
# something useful
end
end
Some more explanation:
http://ola-bini.blogspot.com/2006/09/ruby-singleton-class.html
http://www.klankboomklang.com/2007/09/21/the-singleton-class/
Also see _why's explanation of metaclasses:
http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
Also regarding "self" and replacing it, I've seen this mentioned a few other places - it's difficult for me to think of a good use-case for that feature, though it would sure confuse me. Perhaps there is one. In any case, it is invalid syntax in Ruby to try to change the value of "self":
>> self = Object.new
SyntaxError: compile error
(irb):1: Can't change the value of self
self = Object.new
^
from (irb):1
from :0
In Ruby, and in all other languages that have this concept of "self" or "this", it's used as a pointer to "here", as in, this current object, or class, or metaclass, or whichever object represents what "here" means. Since Ruby is interpreted line-by-line, "self" means the enclosing object when the compiler encounters that keyword.
class Array
self # Means Array class (which is an object, actually)
def self.class_method
self # still means Array class, since you're in a class method
end
def hello
self # Means the current instance of Array
end
class << self
self # Means the metaclass (or "eigenclass") of the Array
end
end