What happens internally when a module is extended in Ruby? - ruby

Foo = Module.new
class MyClass
include Foo
end
When a module is included in a class, an anonymous proxy class is created and set as MyClass's superclass.
MyClass.ancestors => [MyClass, Foo, ...]
But what happens internally when a module is extended? How does Ruby handle this?

I think what you ask is Object#extend
So with extend, I can include any module's methods into that object.
For example I have a module called HelperModule:
module HelperModule
def foo
puts "from module helper"
end
end
Usage Example 1:
obj = Object.new
obj.extend HelperModule
obj.foo # => "from module helper"
Usage Example 2:
class MyClass
extend HelperModule
end
MyClass.foo # => "from module helper"
Internally, according to Metaprogramming Ruby:
Object#extend() is simply a shortcut that includes a module in the receiver’s eigenclass.
A brief explanation of ruby's methods call :
find the object's class, see if the method defined there
find that class's superclass, see if the method defined there
obj
|
| class
| superclass superclass
---> ObjectClass --------------> SuperClass1 --------------> SuperClass2 ....
The detailed explanation about eigenclass and method call path, please reference this awesome book Metaprogramming Ruby
Thanks

Whats happens internally when a module in extended in Ruby?
When a module M is included in a class C, an anonymous proxy class ⟦M′⟧ (called an include class) is created such that its method table pointer points to M's method table. (Same for the constant table and module variables.) ⟦M′⟧'s superclass is set to C's superclass and C's superclass is set to ⟦M′⟧.
Also, if M includes other modules, the process is applied recursively.
Actually, that's just the default behavior. What really happens is that include calls M.append_features(C), and you can customize all of that behavior by overriding that method.
I find the source code of Module#append_features in Rubinius quite readable.

obj.extend SomeModule is the same as obj.eigenclass.include SomeModule (Note: this is just pseudocode, but you will get the idea...).

In a nutshell, Ruby's include method will emulate inheritance: it will allow the including class access to the included module's instance methods, variables and constants as if they had been defined in the including class itself. Ruby does this by creating an anonymous proxy class (known as an eigenclass or singleton class), as you mentioned, which references the included module, and inserting it into the ancestors of the including class as the immediate superclass. This is what is known as a mixin in Ruby.
Using extend, however, interacts with the singleton class a little bit more:
module Foo
def baz
'baz'
end
end
module Blah
def blah
'blah'
end
end
class Bar
extend Foo
include Blah
def self.magic
'magic'
end
end
Extending Foo in Bar is identical (right down to its implementation in C) to saying
Bar.singleton_class.send( :include, Foo )
This means that it is the singleton class of Bar in which the methods and constants of Foo are essentially embedded, and thus class Bar, being an instance of its singleton class, will inherit this new functionality as so-called 'class' methods. In Ruby, modules and classes can only have instance methods, and thus the creation of a 'class' method will actually just create an instance method in the class's singleton class, to be inherited in this manner.
Bar.baz
# => 'baz'
Bar.magic
# => 'magic'
Bar.blah
# => NoMethodError
Bar.new.baz
# => NoMethodError
Bar.new.magic
# => NoMethodError
Bar.new.blah
# => 'blah'
Here you can see the differences in behavior of include and extend. To verify their behavior with regards to class ancestry, you can ask for the ancestors of Bar and its singleton class, and it will show you that module Blah is the immediate parent of Bar, but module Foo is the immediate parent of the singleton class.
Bar.ancestors
# => [Bar, Blah, Object, Kernel, BasicObject]
Bar.singleton_class.ancestors
# => [Foo, Class, Module, Object, Kernel, BasicObject]
From these results, you can see how inclusion emulates inheritance in the including class, and how extension is merely inclusion within the singleton class.
You might try looking at the answers I got for this question awhile back; they did an excellent job of explaining the behavior of the include and extend functionality.
This article has also helped me understand their differences.

Related

Ruby’s secret trick to avoid “class methods” and keep its type system simple and elegant

From Wikibooks' Ruby Programming/Overview:
When I said that every Ruby object has a class, I lied. The truth is, every object has two classes: a “regular” class and a singleton class. An object’s singleton class is a nameless class whose only instance is that object. Every object has its very own singleton class, created automatically along with the object. Singleton classes inherit from their object’s regular class and are initially empty, but you can open them up and add methods to them, which can then be called on the lone object belonging to them. This is Ruby’s secret trick to avoid “class methods” and keep its type system simple and elegant
The above passage says that Ruby's secret trick to avoid class methods. I don't understand what the author means here. Where is Ruby stopping us to avoid class methods? for an example, look at the example shown below
class Raj
def self.hi
puts 'Hi'
end
def hello
puts 'hello'
end
end
object=Raj.new
object.hello
Raj.hi
As you can see in the preceding example, the class methods can still be created.
yes?
I understand that there are no true class methods in Ruby; instead, they are methods that are created for the Raj object.
But, in any case, it's allowing me to create the method 'hi,' right?
So, what does it mean when it says, 'This is Ruby's secret trick for avoiding "class methods" and keeping its type system simple and elegant'?
I understand that there are no true class methods in Ruby; instead, they are methods that are created for the Raj object.
That's exactly it, though.
def self.hi
puts 'Hi'
end
This is not a class method or static method. Those don't exist in Ruby. That's the whole point. Your class Raj defines an object of type Class. We can see its type with the #class function.
> Raj.class
=> Class
We can also see its ancestors.
> Raj.class.ancestors
=> [Class, Module, Object, PP::ObjectMixin, Kernel, BasicObject]
Class inherits from Module, since (for the most part) classes can do everything modules can. Module, in turn, inherits from Object, which has some modules of its own mixed in (PP:ObjectMixin is for pretty-printing, and Kernel gets you the nice helpers like puts) and eventually inherits from the root class BasicObject.
But this isn't the whole story, for Raj has its own class as well: its singleton class. We can see the full story by calling #singleton_class instead of #class.
> Raj.singleton_class.ancestors
=>
[#<Class:Raj>,
#<Class:Object>,
#<Class:BasicObject>,
Class,
Module,
Object,
PP::ObjectMixin,
Kernel,
BasicObject]
Now there's a lot more going on. Raj is an instance of the singleton class of Raj, which inherits from the singleton class of Object, which in turn inherits from the singleton class of BasicObject, which inherits from Class and all of the stuff we saw before.
So when you define a method on the class Raj, you're defining it (as an instance method) on the singleton class #<Class:Raj>. And that class (currently) has one instance: Raj.
By the way, it's also useful to know that the term "singleton class" is a bit of a lie. As you can see, the class is very much not a singleton in general. For instance, the singleton class of Object, called #<Class:Object> above, actually has several instances: Object, Raj, String, and most Ruby classes. Personally, I prefer to call them eigenclasses for that reason, but "singleton class" is the official (and more well-known) term.
The author is talking about the singleton class in this sentence, there is a really nice article to deep dive into ruby singleton class: https://medium.com/#leo_hetsch/demystifying-singleton-classes-in-ruby-caf3fa4c9d91
Here is a nice example extracted from this article:
class Vehicle
def initialize(kms)
#kms = kms
end
def drive
puts "let's go!"
end
end
car = Vehicle.new(1000)
bus = Vehicle.new(3000)
def car.drive
print "I'm driving a car! "
super
end
car.drive # "I'm driving a car! let's go!"
bus.drive # "let's go!"
As you can see, here the #drive method has been overridden but only for the car object, the bus object is still using the #drive method defined in the Vehicle class.
This new method is defined on the singleton class (or shadow class) of the object, this is allowing you to define new methods on the fly on an object without polluting all the objects of this class.
This means that Ruby doesn't implement class methods.
Indeed, the Ruby OBJECT Model, allows you to "emulate" the definition of class methods by defining instance methods on the Eigenclass:
class Greeting
def self.hello
'hello world!'
end
def self.eigenclass
class << self
self
end
end
end
Greeting.eigenclass # => #<Class:Greeting>
Greeting.eigenclass.name # => nil
Greeting.singleton_methods # => [:hello, :eigenclass]
Greeting.eigenclass.instance_methods(false) # => [:hello, :eigenclass]
First, we define a Greeting.eigenclass method. This method returns self in the context of the eigenclass — by using the class << self ... end syntax. In this case, self contains an unnamed instance of the class Class (a.k.a an anonymous class). This anonymous class keeps track of the class to which it is attached — the Greeting class in our case.
Then, we can see that the singleton methods of the Greeting class are the instance methods of the Greeting eigenclass.
Feel free to have a look to this very detailed article to learn more about this concept.
To illustrate #Sébastien P.'s answer:
dice = [1,2,3,4,5,6] #an ordinary array instance
def dice.throw #now it has an extra
sample
end
p dice.throw #=>3

Why do methods inside a class become instance methods instead of becoming singleton methods of the class itself?

Suppose I have the following simple class:
class C
p self # => C
def self.foo
puts "foo"
end
def bar
puts "bar"
end
end
p C.foo # => "foo"
p C.bar # => "`<main>': undefined method `bar' for C:Class (NoMethodError)"
I know that self.foo defines foo to be an instance method inside the singleton class of C.
Why does the second method not get defined inside the singleton class of C like the first one? self is still C when this method is defined.
It works similarly to message sends and constant lookup:
The general format of a message send is foo.bar, which sends the message bar to foo. If you leave out foo, the message will be sent to the default receiver (which is self).
The general format of a constant lookup is Foo::Bar, which looks up the constant Bar in the module Foo. If you leave out Foo, the constant will be looked up in the default constant context (or cref).
The general format of a method definition is def foo.bar, which defines the method bar in the singleton class of foo. If you leave out foo, the method will be defined in the default definition context (or default definee):
At the top-level, the default definee is Object. (Also, the methods become private.)
Within a module declaration body, the default definee is self (and not self's singleton class, like you assumed!)
Within a method body, the default definee is the syntactically enclosing module. (Put another way: def doesn't change the default definee.)
instance_eval changes the default definee to the receiver's singleton class
class_eval changes the default definee to the receiver
it's a convention of the ruby language. (conceptually you can think of this like you think about static methods in Java. they are not associated with any instance of the class but with the class itself)
bar is going to be a method on objects instantiated from C.
self.bar is going to be a method on C itself.
What's interesting in Ruby is that C class itself is an object (so the class definition that you can use to build objects is an object itself). That's where the self comes from (i.e. define this on myself vs define this from objects that will be built using me as a blueprint) Read more on this: Ruby craziness: Class vs Object?

How does 'defining a method' work semantically?

Background:
Here is what I understand about the object model (relative to my question below):
self always references the receiver in the current stack frame.
When you are in the top level and you say def someMethod the implicit receiver is self and you are creating a method which sits in the anonymous class associated with self. This anonymous class happens to sit just under Object (self is an instance of the Object class) so when you call someMethod, Ruby "takes a step to the right", and it lands in the anonymous class, thus finding and invoking your method.
This is similar to what goes on when you define methods inside of class definitions. If, when inside a class definition, you say: def self.classMethod you are creating a method in an anonymous class that sits just underneath the Class class. Methods of this class, existing "to the right" of the class currently being defined will not be visible to instances of the new class.
My Question:
How does "defining a method in a class" happen in the first place? (semantically)
Class objects aren't supposed to be different from normal objects, right?
From what I understand about message handling, Class objects have a table as a part of their state, presumable meaning it is an instance variable, that has the names of all of its instance methods. This is how the method look up works. (If Ruby doesn't find it , it goes up one and again, presumably the directions to the next link up the chain are a part of the state of the current Class object.)
Since Ruby doesn't really care about object type, I presume it doesn't care that it's looking in Class objects specifically when doing method look up. Rather, it's just following references and looking for bits of state with certain names. So, could I create my own "class objects" without using the class keyword that don't inherit from the Class class?
If that question doesn't make any sense, then I apologize. I just want to know what happens when the interpreter encounters the def keyword.
When you write 'def something' in ruby you are adding a method to a module. Sometimes that module is a 'class' (a type of module). It all depends on what 'self' is at the time:
class Foo
# right now self is 'Foo'
class << self
# right now self is 'Class:Foo'
end
def self.bar
# right now self is 'Foo'
end
end
def Foo.buz
# right now self is 'Foo'
end
obj = Foo.new
def obj.baz
# right now self is 'Foo:0x007fe8a632fa78' (an instance)
end
A class is just a type of module. Subclassing is one way of creating a pointer from One module up to another:
class Foo
end
class Bar < Foo
end
> Bar.ancestors
=> [Bar, Foo, Object, Kernel, BasicObject]
Another way is including mixins:
module Mixin
end
class Foo
include Mixin
end
> Foo.ancestors
=> [Foo, Mixin, Object, Kernel, BasicObject]
Method dispatch works on what exists in the inheritance chain. It's a list (not a tree) of parent modules and is ordered based on when the inheritance was created:
# bar.rb
module MixinA
def something
puts "MixinA"
super
end
end
module MixinB
def something
puts "MixinB"
end
end
class Base
def something
puts "Base"
super
end
end
class Sub < Base
include MixinB
include MixinA
def something
puts "Sub"
super
end
end
obj = Sub.new
obj.something
Run:
$ ruby bar.rb
Sub
MixinA
MixinB
Inspecting the chain:
> Sub.ancestors
=> [Sub, MixinA, MixinB, Base, Object, Kernel, BasicObject]
When a method call happens in walks this list looking for the method in question. If none of the modules in the chain have the method then the search starts over at the top but instead calls method_missing. In either case, the first resolution found wins.
Yehuda Katz wrote a good article on this stuff in 2009:
http://yehudakatz.com/2009/11/15/metaprogramming-in-ruby-its-all-about-the-self/

module_function for Ruby Class

As I understand ruby classes, they are almost the same as modules except with an added functionality of being able to instantiate it. As Class inherits from Module, I assumed that then every class (objects of class Class) would have access to module_function, but it does not seem to be the case. When I did a difference of Module and Class' private_instance_methods, I found that Module has 3 methods more than Class - [:append_features, :extend_object, :module_function]
How were these functions removed from the call chain for Class objects and more importantly why?
Those core features are implemented in C, so discussing about that does not have generality, and is not useful. Within Ruby, you can undefine an inherited method without undefining the method in the superclass by using undef.
class Foo
def foo; end
end
class Bar < Foo
undef :foo
end
Foo.new.foo
# => nil
Bar.new.foo
# => NoMethodError: undefined method `foo' for #<Bar:0x007f85c3ce3330>
append_features is a hook to be called right before a module is include-d, which a module can be, but not a class.
extend_object is a hook to be called right before a module is extend-ed, which a module can be, but not a class.
The purpose of module_function is to double the method as a class method and a private instance method, latter of which is useful when you include that module, which can be done with a module but not with a class.

Delegator through BasicObject transparency

Context: I am trying to put up a Decorator pattern in Ruby. As a Decorator should delegate all unknown methods to the underlying objects, I used the Delegator class.
I could have used SimpleDelegator but I wanted to fully understand what I was doing.
So the basic code I came out with was :
class Decorator < Delegator
def initialize(component)
super
#component = component
end
def __setobj__(o); #component = o end
def __getobj__; #component end
def send(s, *a); __send__(s, *a) end
end
Which is ~exactly the same as the implementation of SimpleDelegator. Seems good.
But the thing I did not want was for the code handling the Decorator to know it is manipulating a Decorator. I want full transparency.
At this moment Decorator.new(Object.new).class returned Decorator
So I tinkered a bit and came up with this :
class Decorator < Delegator
undef_method :==
undef_method :class
undef_method :instance_of?
# Stores the decorated object
def initialize(component)
super
#component = component
end
def __setobj__(o); #component = o end
def __getobj__; #component end
def send(s, *a); __send__(s, *a) end
end
This way, I can safely use class or instance_of? on my Decorated object, it will send the method to the underlying object via method_missing (which is implemented by Delegator).
The thing is : I don't understand why I had to undef :class and :instance_of?. I can see that BasicObject defines :== so I had to undefine it but what about those two ?
I looked at the BasicObject documentation and a bit in the C code but did not find anything. I looked the same at the Delegator documentation and code, and did not find anything either.
It seems Delegator include the Kernel module, but Kernel#class or Kernel#instance_of? don't exist.
Where those two method came from ? Why did I need to undefine them if they were not implemented at all ?
I guess I must be missing something about Ruby's object model or something.
Thanks.
You can get a hint by inspecting the method:
Decorator.instance_method(:class)
# => #<UnboundMethod: Decorator(#<Module:0x00000102137498>)#class>
The method's owner is Decorator but actually defined in #<Module:0x00000102137498>. So there is an anonymous module that defines it. Interesting... let's look at:
Decorator.ancestors
# => [Decorator, Delegator, #<Module:0x00000102137498>, BasicObject]
There's that module again, between Delegator and BasicObject. So Delegator doesn't directly derive from BasicObject. If you look at the source code in lib/delegate.rb you find:
class Delegator < BasicObject
kernel = ::Kernel.dup
kernel.class_eval do
[:to_s,:inspect,:=~,:!~,:===,:<=>,:eql?,:hash].each do |m|
undef_method m
end
end
include kernel
# ...
So a copy of the Kernel module is made, which doesn't have to_s, inspect, etc... but still has class and instance_of?. It's included in Delegator and that's where they come from.
Note that Object inherits the same methods by including the Kernel module (but it includes the full module, of course):
42.method(:class) # => #<Method: Fixnum(Kernel)#class>
This is stated in the Object doc:
Object mixes in the Kernel module, making the built-in kernel
functions globally accessible. Although the instance methods of Object
are defined by the Kernel module, we have chosen to document them here
for clarity.

Resources