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.
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 anticipate that I am not trying to do anything practical here, just trying to understand some deeper Ruby concepts.
Supppose I have the following code
class Bookshelf
#book_qty = 100 # class instance var
class << self
attr_accessor :books_qty
end
def initialize
#book = "This book is in every object as an object instance variable"
end
# so far so good, but what happens with...
def self.initialize # what would be this called on ?
puts " and at what step would this be printed, if ever?"
# I thought it would be printed when the class code is parsed first time,
# but no
end
# or also
class << self
def initialize
puts "same here"
end
end
end
I know it might not make sense or might be too intricately related on how Ruby internals work, but, if by chance anyone has been puzzled too by this and knows the answer... please share it :)
There is no purpose to defining initialize for the singleton class (whether you use def self. or class << self). initialize is only called by Class#new and...
Bookshelf.singleton_class.new
# TypeError: can't create instance of singleton class
that's not allowed.
If you want code to be executed the first time a class is parsed, just put it in the class
class Bookshelf
puts "class defined!"
end
In some cases, it does make sense to define a custom constructor, but I wouldn't call the method initialize, since the instance method you override to customise initialisation is also called initialize. That would be a little confusing.
def self.initialize # what would be this called on ?
If you define a method like this, you can invoke it by sending the method directly to the class:
Bookshelf.initialize
Same thing applies for methods defined inside class << self.
As mentioned, it does make sense to define custom constructors for a class. Sometimes just for readability's sake:
class Bookshelf
attr_accessor :book_qty
def self.with_quantity(quantity)
new(quantity)
end
def initialize(quantity)
self.book_qty = quantity
end
end
Now you could instantiate a Bookshelf like this:
bs = Bookshelf.with_quantity 100
bs.quantity # => 100
You actually call .new on the singleton class of Bookshelf. And #initialize is basically just a hook for the instance to tweak its initialisation.
How you could access class instance variables
class Bookshelf
#book_qty = 1000
class << self
attr_accessor :book_qty
end
end
Bookshelf.book_qty # => 1000
Bookshelf.book_qty = 2000
Bookshelf.book_qty # => 2000
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 am a Ruby starter. I found both of these are quite similar (in output), but i couldn't understand the difference in the below context. For example, I have a class
class Say
def self.hello
puts "hello"
end
end
and can be extended like this
class << Say
def hi
puts "hi"
end
end
and also like this
Say.class_eval do
def self.bye
puts "bye"
end
end
When should I use << and when class_eval?
class_eval doesn't really have anything to do with class << className.
A.class_eval do
...
end
is equivalent to
class A
...
end
with a few differences. class_eval uses a block (or a string, but ignoring that for the moment) which means it closes over the containing lexical scope. In other words you can use local variables from the surrounding scope. The common class block introduces a brand new scope. Likewise you can create the block and pass it to many different class_eval's, and the body of the block will be executed in the context of the class you are calling class_eval on.
class << className opens the singleton class of className, allowing you to define class methods.
class << A
def foo
...
end
end
Is the same as
def A.foo
...
end
Note that they are oly class methods if A happens to be a class (almost) all objects in ruby have singleton classes and you can define methods for them using either of those two syntaxes. The advantage of class << obj is mainly if you're defining many singleton methods in one go.
As already said class_eval has really not much to do with
class <<self
even if they seem to do the same thing in your example (while the effect is similar it does not do the same, there are subtle differences).
Here is another example where the usage of the second form is far more clearer:
class A
end
a = A.new
b = A.new
class <<b
def say_hi
puts "Hi !"
end
end
b.say_hi # will print "Hi !"
a.say_hi # will raise an undefined method
a and b are both objects of the same class A but we added a method to the metaclass of b so the method say_hi is only available to the b object.
What does class << self do in Ruby?
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"
Now, to answer the question: 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 String
class << self
def value_of obj
obj.to_s
end
end
end
String.value_of 42 # => "42"
This can also be written as a shorthand:
class String
def self.value_of obj
obj.to_s
end
end
Or even shorter:
def String.value_of obj
obj.to_s
end
When inside a function definition, self refers to the object the function is being called with. In this case, class << self opens the singleton class for that object; one use of that is to implement a poor man's state machine:
class StateMachineExample
def process obj
process_hook obj
end
private
def process_state_1 obj
# ...
class << self
alias process_hook process_state_2
end
end
def process_state_2 obj
# ...
class << self
alias process_hook process_state_1
end
end
# Set up initial state
alias process_hook process_state_1
end
So, in the example above, each instance of StateMachineExample has process_hook aliased to process_state_1, but note how in the latter, it can redefine process_hook (for self only, not affecting other StateMachineExample instances) to process_state_2. So, each time a caller calls the process method (which calls the redefinable process_hook), the behaviour changes depending on what state it's in.
I found a super simple explanation about class << self , Eigenclass and different type of methods.
In Ruby, there are three types of methods that can be applied to a class:
Instance methods
Singleton methods
Class methods
Instance methods and class methods are almost similar to their homonymous in other programming languages.
class Foo
def an_instance_method
puts "I am an instance method"
end
def self.a_class_method
puts "I am a class method"
end
end
foo = Foo.new
def foo.a_singleton_method
puts "I am a singletone method"
end
Another way of accessing an Eigenclass(which includes singleton methods) is with the following syntax (class <<):
foo = Foo.new
class << foo
def a_singleton_method
puts "I am a singleton method"
end
end
now you can define a singleton method for self which is the class Foo itself in this context:
class Foo
class << self
def a_singleton_and_class_method
puts "I am a singleton method for self and a class method for Foo"
end
end
end
Usually, instance methods are global methods. That means they are available in all instances of the class on which they were defined. In contrast, a singleton method is implemented on a single object.
Ruby stores methods in classes and all methods must be associated with a class. The object on which a singleton method is defined is not a class (it is an instance of a class). If only classes can store methods, how can an object store a singleton method? When a singleton method is created, Ruby automatically creates an anonymous class to store that method. These anonymous classes are called metaclasses, also known as singleton classes or eigenclasses. The singleton method is associated with the metaclass which, in turn, is associated with the object on which the singleton method was defined.
If multiple singleton methods are defined within a single object, they are all stored in the same metaclass.
class Zen
end
z1 = Zen.new
z2 = Zen.new
class << z1
def say_hello
puts "Hello!"
end
end
z1.say_hello # Output: Hello!
z2.say_hello # Output: NoMethodError: undefined method `say_hello'…
In the above example, class << z1 changes the current self to point to the metaclass of the z1 object; then, it defines the say_hello method within the metaclass.
Classes are also objects (instances of the built-in class called Class). Class methods are nothing more than singleton methods associated with a class object.
class Zabuton
class << self
def stuff
puts "Stuffing zabuton…"
end
end
end
All objects may have metaclasses. That means classes can also have metaclasses. In the above example, class << self modifies self so it points to the metaclass of the Zabuton class. When a method is defined without an explicit receiver (the class/object on which the method will be defined), it is implicitly defined within the current scope, that is, the current value of self. Hence, the stuff method is defined within the metaclass of the Zabuton class. The above example is just another way to define a class method. IMHO, it's better to use the def self.my_new_clas_method syntax to define class methods, as it makes the code easier to understand. The above example was included so we understand what's happening when we come across the class << self syntax.
Additional info can be found at this post about Ruby Classes.
What class << thing does:
class Hi
self #=> Hi
class << self #same as 'class << Hi'
self #=> #<Class:Hi>
self == Hi.singleton_class #=> true
end
end
[it makes self == thing.singleton_class in the context of its block].
What is thing.singleton_class?
hi = String.new
def hi.a
end
hi.class.instance_methods.include? :a #=> false
hi.singleton_class.instance_methods.include? :a #=> true
hi object inherits its #methods from its #singleton_class.instance_methods and then from its #class.instance_methods.
Here we gave hi's singleton class instance method :a. It could have been done with class << hi instead.
hi's #singleton_class has all instance methods hi's #class has, and possibly some more (:a here).
[instance methods of thing's #class and #singleton_class can be applied directly to thing. when ruby sees thing.a, it first looks for :a method definition in thing.singleton_class.instance_methods and then in thing.class.instance_methods]
By the way - they call object's singleton class == metaclass == eigenclass.
А singleton method is a method that is defined only for a single object.
Example:
class SomeClass
class << self
def test
end
end
end
test_obj = SomeClass.new
def test_obj.test_2
end
class << test_obj
def test_3
end
end
puts "Singleton's methods of SomeClass"
puts SomeClass.singleton_methods
puts '------------------------------------------'
puts "Singleton's methods of test_obj"
puts test_obj.singleton_methods
Singleton's methods of SomeClass
test
Singleton's methods of test_obj
test_2
test_3
In fact if you write any C extensions for your Ruby projects there is really only one way to define a Module method.
rb_define_singleton_method
I know this self business just opens up all kinds of other questions so you could do better by searching each part.
Objects first.
foo = Object.new
Can I make a method for foo?
Sure
def foo.hello
'hello'
end
What do I do with it?
foo.hello
==>"hello"
Just another object.
foo.methods
You get all the Object methods plus your new one.
def foo.self
self
end
foo.self
Just the foo Object.
Try to see what happens if you make foo from other Objects like Class and Module. The examples from all the answers are nice to play with but you have to work with different ideas or concepts to really understand what is going on with the way the code is written. So now you have lots of terms to go look at.
Singleton,
Class,
Module,
self,
Object,
and Eigenclass was brought up but Ruby doesn't name Object Models that way. It's more like Metaclass.
Richard or __why shows you the idea here.
http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html
And if the blows you away then try looking up Ruby Object Model in search.
Two videos that I know of on YouTube are Dave Thomas and Peter Cooper. They try to explain that concept too. It took Dave a long time to get it so don't worry.
I'm still working on it too. Why else would I be here?
Thanks for your question.
Also take a look at the standard library. It has a Singleton Module just as an FYI.
This is pretty good.
https://www.youtube.com/watch?v=i4uiyWA8eFk