Why would I want to add anything to a class using class << Class
syntax?
class Fun
def much_fun
# some code here
end
end
class << Fun # the difference is here!
def much_more_fun
# some code here
end
end
instead of using the monkey patching/duck punching method:
class Fun
def much_fun
# some code here
end
end
class Fun # the difference is here!
def much_more_fun
# some code here
end
end
While reading Why's Poignant Guide to Ruby I came across:
Why defines a class LotteryDraw
:
class LotteryDraw
# some code here
def LotteryDraw.buy( customer, *tickets )
# some code here as well
end
end
and after a while adds a method to the LotteryDraw
class:
class << LotteryDraw
def play
# some code here
end
end
saying that:
When you see
class << obj
, believe in your heart, I’m adding directly to the definition ofobj
.
What is the purpose of this syntax? Why did Why decide to do it this way instead of using the monkey patching method?
These are some related questions and websites:
class << Class
syntax.A little more explanation is needed. In ruby almost every single object can create a weird thing called an instance class. This thing is just like a normal class, the main difference is that it has only one single instance and that that instance is created before that class.
In short, having class A, you can do:
a = A.new
b = A.new
Both, a
and b
are now the instances of class A and have an access to all the instance method defined within this class. Now let's say, we want to add an extra method which can only be accesses by a
, but not by b
(this might be useful in some cases, but rather avoid it if possible). All the methods are defined within the classes, so it seems we need to add it to class A, but this way it will be accessible by b
as well. In this case we need to create an instance class for a
object. To do that, we use class << <object>
syntax:
class << a
def foo
end
end
a.foo #=> nil
b.foo #=> undefined method
In short, class << <object>
opens an instance class for given object, allowing to define additional instance methods for given instance, which will not be available on any other objects.
Now, with that being said: in Ruby, classes are jest instances of class Class. This:
class A
end
Is almost equivalent to (differences not important here)
A = Class.new
So if classes are objects, they can create their instance classes.
class << A
def foo
end
end
A.foo #=> nil
Class.new.foo #=> undefined method
It is commonly used to add so-called class method to given class, the point however is that in fact you are creating an instance method on class' instance class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With