How can a class call a class method that is defined on a singleton class?

Hello guys. I’m new here and on Ruby, so bear with me on this one.

I know that when we define a class method on a class, it’s created a
singleton class that gets the definition of that method, and from then
on, that method is an instance method of that singleton class(i got this
conclusion from tests, but i might be wrong, so feel free to correct
me).

My question is, how can i call a class method on a class X with
X.classMethod if the method is defined on a singleton class as an
instance method of that class(i am not asking how can i do it. It is
what happens.).

It confuses me even more, because i noticed(running some tests) that
the singleton class of a class is not even hierarchically related to the
class it comes from, so, how is a class method call resolved to the
singleton class? And more precisely: how is the class calling a method
on a singleton class that is an instance method, without any instance.

I hope i did not confuse you.

Thank you.

Dear Lazarus,

It’s a little confusing at first. But I think you will get it easily.

+++

First

+++

How do I define an instance method?

class MyClass
def my_instance_method
end
end

my_object = MyClass.new

The instance method defined on our class …

MyClass.instance_methods.grep(/my/)

=> [:my_instance_method]

… is a method callable on an instance of the class

my_object.methods.grep(/my/)

=> [:my_instance_method]

+++

Second

+++

How do I define an instance method on my singleton class (of my

class)?

class MyClass
class << self
def my_eigen_instance_method
end
end
end

eigen = MyClass.singleton_class

The instance method defined on our eigen class …

eigen.instance_methods.grep(/eigen/)

=> [:my_eigen_instance_method]

… is a method (singleton method) callable on the class itself

MyClass.methods.grep(/eigen/)

=> [:my_eigen_instance_method]

MyClass.singleton_methods.grep(/eigen/)

=> [:my_eigen_instance_method]

+++

To the questions…

On Sun, Feb 9, 2014 at 7:14 PM, Lazarus S. [email protected]
wrote:

Hello guys. I’m new here and on Ruby, so bear with me on this one.

I know that when we define a class method on a class, it’s created a
singleton class that gets the definition of that method, and from then
on, that method is an instance method of that singleton class(i got this
conclusion from tests, but i might be wrong, so feel free to correct
me).

My question is, how can i call a class method on a class X with
X.classMethod if the method is defined on a singleton class as an
instance method of that class(i am not asking how can i do it. It is
what happens.).

The method lookup chain searches first for methods defined on its
metaclass.

It confuses me even more, because i noticed(running some tests) that
the singleton class of a class is not even hierarchically related to the
class it comes from,

We could say that a class is an instance of its metaclass.
Or… the metaclass is “inserted” between MyClass and its class
(Class) in the method lookup chain.

so, how is a class method call resolved to the
singleton class?

(Same as above.)

And more precisely: how is the class calling a method
on a singleton class that is an instance method, without any instance.

MyClass is an object (instance) also even if its a class.
Or… in Ruby the classes are also objects.

Arup R. raised a good question. If the Metaclass is above
the normal class, how it the method called first on the metaclass, and
not on the normal class. I assume this was is question. I am not sure,
but i think it’s like(and as referred previously), the normal class is
an instance of the meta class, and in that case, the call is done on the
metaclass because is the class that defines the callable method and
which is right above the normal class just like a normal call
resolution.

Is this correct?, or at least “correct” :)?

Abinoam Jr. wrote in post #1136161:

My question is, how can i call a class method on a class X with
X.classMethod if the method is defined on a singleton class as an
instance method of that class(i am not asking how can i do it. It is
what happens.).

The method lookup chain searches first for methods defined on its
metaclass.

It confuses me even more, because i noticed(running some tests) that
the singleton class of a class is not even hierarchically related to the
class it comes from,

We could say that a class is an instance of its metaclass.

Technically No. :slight_smile:

class Foo
def bar
12
end
end

singleton_klass = Foo.singleton_class
Foo.instance_of? singleton_klass # => false

The method lookup chain searches first for methods defined on its
metaclass.
? Although it is correct .

class Foo
def bar
12
end
end

foo = Foo.new

def foo.bar
11
end

foo.bar # => 11

Then how is Or… the metaclass is “inserted” between MyClass and its
class (Class) in the method lookup chain.
true ?

Abinoam Jr. wrote in post #1136557:

NOTE:
I’m not a “computer scientist”.

It seems you are by “Nature”, don’t know if by “Profession”!

Hi Arup, (take the text bellow at your own risk :wink: )

I would disagree with you :slight_smile:

I am happy as you disagreed. :slight_smile:

And Foo is the superclass of Sfoo and “inherits” methods from it.

Sfoo.superclass #=> Foo

Great to know, never digged till that part.

So, If I want to know what Class object created a given object I

would call #class on it.

That was the “formula” used to do it, and it’s also the superclass

of its metaclass.

foo.class #=> Foo

If I want to know what (real) class the object is a direct instance

of, I would call #singleton_class on it

This is to what the “klass” pointer is really pointing.

That’s why there’s two methods with the word “class” on the name :wink:

foo.singleton_class #=> #<Class:#Foo:0x00000001fb84b0>

Awesome point. Very confusing, but when I read it 6 times, started to
believe this.

There’s a short video here that clarifies it a little bit.
http://drtom.ch/posts/2011/12/11/Rubys_Object_Model_and_Eigenclasses/

Here is an earthquake happened in my Ruby knowledge, due to you. Thanks
for that.

NOTE:
I’m not a “computer scientist”.
So, I would really appreciate a revision of the text bellow by a “well
grounded rubyist”, a "confident ruby"ist, a "ruby best practice"ing
one or any senior rubyist that loves this language as much as I do.
Any feedback are really welcome!

Hi Arup, (take the text bellow at your own risk :wink: )

I would disagree with you :slight_smile:

Classes in Ruby are objects also.

Think of them as objects that has special methods (#new, #alocate,
#initialize) and are capable of creating other objects each one of
them being instances of its own metaclass that inherits from this
Class object.
So a Class object is kind of a “formula” to summon objects and their
metaclasses.

class Foo
def hello
puts “Hello from #hello instance method defined on Foo being
called at #{self}”
end

def hi
puts “Hi from #hi instance method defined on Foo being called at
#{self}”
end
end

foo = Foo.new

Sfoo = foo.singleton_class

class Sfoo
def hello
puts “Hello from #hello instance method defined on Sfoo being
called at #{self}”
puts “Calling super…”
super
end
end

foo.hello will call the Sfoo#hello and from them it explicitly call

super that will call a method with the same name on the superclass

foo.hello

But, if foo is an instance of Sfoo and not of Foo, how can I call #hi

on foo?

foo.hi # It works

That’s because there’s no #hi method defined on Sfoo

Sfoo.instance_methods(false) #=> [:hello]
Foo.instance_methods(false) #=> [:hello, :hi]

And Foo is the superclass of Sfoo and “inherits” methods from it.

Sfoo.superclass #=> Foo

So, If I want to know what Class object created a given object I

would call #class on it.

That was the “formula” used to do it, and it’s also the superclass

of its metaclass.

foo.class #=> Foo

If I want to know what (real) class the object is a direct instance

of, I would call #singleton_class on it

This is to what the “klass” pointer is really pointing.

That’s why there’s two methods with the word “class” on the name :wink:

foo.singleton_class #=> #<Class:#Foo:0x00000001fb84b0>

There’s a short video here that clarifies it a little bit.
http://drtom.ch/posts/2011/12/11/Rubys_Object_Model_and_Eigenclasses/

And the book “Metaprogramming Ruby: Program Like the Ruby Pros” by
Paolo Perrotta treats this subject pretty deeply.

Now let’s wait for some feedback just to be sure there’s no
misinformation in my post.

Best regards,
Abinoam Jr.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs