Forum: Ruby Understanding Ruby Classes, Objects and Methods.

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2013-03-13 23:20
Dear Rubyists,

I recently wrote a document about Ruby's classes, objects and methods.
The goal was to find out whether I understand them right and whether I
can explain it simply enough in writing.

It is available on the Google Drive:
http://bit.ly/ruby-classes-and-objects

With the help of some text, a few pictures and some examples, it tries
to explain these basic concepts in Ruby. I have taken help from Dave
Thomas's book and Matz/Flanagan book but the document is my own
interpretation. It has become rather long, but I have worked hard on
being correct and precise.

I will be honored if you read and review (and help correct errors in)
the document.

Thanks and Best Regards,
Kedar Mhaswade
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2013-03-14 12:53
(Received via mailing list)
On Wed, Mar 13, 2013 at 11:20 PM, Kedar Mhaswade <lists@ruby-forum.com>
wrote:
> to explain these basic concepts in Ruby. I have taken help from Dave
> Thomas's book and Matz/Flanagan book but the document is my own
> interpretation. It has become rather long, but I have worked hard on
> being correct and precise.
>
> I will be honored if you read and review (and help correct errors in)
> the document.

abc is an instance of String
This is not true. Said expression is a constructor of a String which
will return a different String instance on every evaluation.

"Depending upon the data type of the object, a variable is a name for
the object itself or a reference to it."
In an introductory text I would not _start_ with this statement.
Better: "A variable is a place that stores a reference to an object."

Same for your treatment of "immediate values". This is really an
implementation detail which should be taught much later.  I think it
helps understanding if one does _not_ bring this up that early.
Actually, from a point of view of the user of the language it does not
matter _at all_ (only for performance, but not functionality wise).

"If the method were not found in String, Ruby would have followed the
superclass (sc, green arrow) links in search for the method
definition." and "It creates a new anonymous class object and inserts
it into Foos superclass chain!"
This is not true.  The chain of classes and modules found via
Module#ancestors is traversed instead.  There is no need for a new
anonymous class.  The only place where new classes are automatically
allocated is the singleton class of an instance.

I stopped reading there as I found your diagram about singleton quite
complicated and unclear.

Cheers

robert
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2013-03-14 13:57
Thanks, Robert!

> abc is an instance of String
> This is not true. Said expression is a constructor of a String which
> will return a different String instance on every evaluation.

I don't find that statement in the doc. I only have:

2. "abc" is an instance of String.

and I believe that is correct because String is the class of all strings
in Ruby.

>
> "Depending upon the data type of the object, a variable is a name for
> the object itself or a reference to it."
> In an introductory text I would not _start_ with this statement.
> Better: "A variable is a place that stores a reference to an object."
> Same for your treatment of "immediate values". This is really an
> implementation detail which should be taught much later.  I think it
> helps understanding if one does _not_ bring this up that early.
> Actually, from a point of view of the user of the language it does not
> matter _at all_ (only for performance, but not functionality wise).

I agree. But integers is what many of us start with playing in irb. So,
I thought it was appropriate to recognize the difference between
instances of String (e.g. "abc") and those of an Integer (e.g. 1).

>
> "If the method were not found in String, Ruby would have followed the
> superclass (sc, green arrow) links in search for the method
> definition." and "It creates a new anonymous class object and inserts
> it into Foos superclass chain!"
> This is not true.  The chain of classes and modules found via
> Module#ancestors is traversed instead.  There is no need for a new
> anonymous class.  The only place where new classes are automatically
> allocated is the singleton class of an instance.
>

I see. But I thought Dave Thomas also says something similar (in his
book) to what I wrote. The topic is about including Modules in Classes.
Even if you say that the chain returned by ancestors is traversed, where
is the reference for code for something like Mod#m? Since the same
module Mod can be included in several classes, an instance of anonymous
class for each including class seems right. But I agree, I don't yet
know how this happens internally in the interpreter.

Also, I tried to logically explain why included module's methods _have
to_ get preference over those inherited from superclasses.

> I stopped reading there as I found your diagram about singleton quite
> complicated and unclear.
>

Not a problem. I will try to clarify the diagrams. Alas, they are not
doing their job :-(. But I believe they are correct (and this stuff is
complex).

> Cheers
>
> robert
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2013-03-14 14:29
(Received via mailing list)
On Thu, Mar 14, 2013 at 1:57 PM, Kedar Mhaswade <lists@ruby-forum.com>
wrote:
> Thanks, Robert!

You're welcome!

>> abc is an instance of String
>> This is not true. Said expression is a constructor of a String which
>> will return a different String instance on every evaluation.
>
> I don't find that statement in the doc. I only have:
>
> 2. "abc" is an instance of String.

Yes, that's it.

> and I believe that is correct because String is the class of all strings
> in Ruby.

irb(main):001:0> 5.times { s = "abc"; p s.object_id }
-1073589128
-1073589178
-1073589208
-1073589228
-1073589268
=> 5

> I agree. But integers is what many of us start with playing in irb. So,
> I thought it was appropriate to recognize the difference between
> instances of String (e.g. "abc") and those of an Integer (e.g. 1).

The fact that Fixnums are immediate values is _completely_ irrelevant
for how they are used.

> book) to what I wrote. The topic is about including Modules in Classes.
I don't have the book handy.  Maybe you can quote the relevant text.

> Even if you say that the chain returned by ancestors is traversed, where
> is the reference for code for something like Mod#m? Since the same
> module Mod can be included in several classes, an instance of anonymous
> class for each including class seems right. But I agree, I don't yet
> know how this happens internally in the interpreter.

So you say you do not know how it works but claim there is an
anonymous class - solely because it "seems right"?  Why does it "seem
right"?  I had though you wanted to convey facts.

> Also, I tried to logically explain why included module's methods _have
> to_ get preference over those inherited from superclasses.

You do not need anonymous classes for that.

>> I stopped reading there as I found your diagram about singleton quite
>> complicated and unclear.
>
> Not a problem. I will try to clarify the diagrams. Alas, they are not
> doing their job :-(. But I believe they are correct (and this stuff is
> complex).

I didn't say "all".  Just the singleton class diagram put me off.

Cheers

robert
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2013-03-14 14:42
>>> abc is an instance of String
>>> This is not true. Said expression is a constructor of a String which
>>> will return a different String instance on every evaluation.
>>
>> I don't find that statement in the doc. I only have:
>>
>> 2. "abc" is an instance of String.
>
> Yes, that's it.
>
And do you suggest that that statement is "not true"?

>> and I believe that is correct because String is the class of all strings
>> in Ruby.
>
> The fact that Fixnums are immediate values is _completely_ irrelevant
> for how they are used.

Perhaps. All I wanted to say was is reference to the phrase "is a".
That's when I introduced variables and I thought the difference in
intermediate values and references should be clarified at that point.
Since then, I have clarified the text even further.

>
>> book) to what I wrote. The topic is about including Modules in Classes.
> I don't have the book handy.  Maybe you can quote the relevant text.
>
>> Even if you say that the chain returned by ancestors is traversed, where
>> is the reference for code for something like Mod#m? Since the same
>> module Mod can be included in several classes, an instance of anonymous
>> class for each including class seems right. But I agree, I don't yet
>> know how this happens internally in the interpreter.
>
> So you say you do not know how it works but claim there is an
> anonymous class - solely because it "seems right"?  Why does it "seem
> right"?  I had though you wanted to convey facts.

Yes. And I should really know what happens internally. But here is what
Dave says in his book (on page 379 of the Programming Ruby PDF --
Version: 2010-11-15 that I purchased from Prag Prog):

----------------------------------------------------------------
To get around this, Ruby uses a clever trick. When you include a module
in class Example, Ruby constructs a new class object, makes it the
superclass of Example, and then sets the superclass of the new class to
be the original superclass of Example. It then references the module
from this new class object in such a way that when you look a method up
in this class, it actually looks it up in the module, as shown in Figure
24.5, on the next page.
----------------------------------------------------------------

Is this not right?
14b5582046b4e7b24ab69b7886a35868?d=identicon&s=25 Joel Pearson (virtuoso)
on 2013-03-14 14:55
Robert is right, your wording is a bit off on this one:

* “abc” is an instance of String *

"abc" is a shortcut (syntactic sugar?) for String.new("abc")
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2013-03-14 15:01
(Received via mailing list)
On Thu, Mar 14, 2013 at 2:42 PM, Kedar Mhaswade <lists@ruby-forum.com>
wrote:
> And do you suggest that that statement is "not true"?
Yes, see above. It's at least imprecise since "abc" does not reference
a single instance of String but it will produce a new instance every
time it is executed.  See the part of my previous mail you did not
quote.

>> anonymous class - solely because it "seems right"?  Why does it "seem
> be the original superclass of Example. It then references the module
> from this new class object in such a way that when you look a method up
> in this class, it actually looks it up in the module, as shown in Figure
> 24.5, on the next page.
> ----------------------------------------------------------------
>
> Is this not right?

I don't know.  But I do know that this is an implementation detail of
MRI which is invisible to the user of the language.  Other than
singleton classes these new class objects cannot in any way be
observed by Ruby programs:

irb(main):001:0> a = Object.superclass.object_id
=> -1073527798
irb(main):002:0> module X end
=> nil
irb(main):003:0> class Object
irb(main):004:1> include X
irb(main):005:1> end
=> Object
irb(main):006:0> b = Object.superclass.object_id
=> -1073527798
irb(main):007:0> a == b
=> true

The information may be right or outdated but it does not necessarily
help users of the language to understand how Ruby works.

Cheers

robert
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2013-03-14 15:02
Joel Pearson wrote in post #1101600:
> Robert is right, your wording is a bit off on this one:
>
> * “abc” is an instance of String *
>
> "abc" is a shortcut (syntactic sugar?) for String.new("abc")

Thank you. Corrected.
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2013-03-14 15:14
Robert Klemme wrote in post #1101602:
> On Thu, Mar 14, 2013 at 2:42 PM, Kedar Mhaswade <lists@ruby-forum.com>
> wrote:
>> And do you suggest that that statement is "not true"?
> Yes, see above. It's at least imprecise since "abc" does not reference
> a single instance of String but it will produce a new instance every
> time it is executed.  See the part of my previous mail you did not
> quote.

OK. Clarified. Thank you.

>
>>> anonymous class - solely because it "seems right"?  Why does it "seem
>> be the original superclass of Example. It then references the module
>> from this new class object in such a way that when you look a method up
>> in this class, it actually looks it up in the module, as shown in Figure
>> 24.5, on the next page.
>> ----------------------------------------------------------------
>>
>> Is this not right?
>
> I don't know.  But I do know that this is an implementation detail of
> MRI which is invisible to the user of the language.  Other than
> singleton classes these new class objects cannot in any way be
> observed by Ruby programs:
>
> irb(main):001:0> a = Object.superclass.object_id
> => -1073527798
> irb(main):002:0> module X end
> => nil
> irb(main):003:0> class Object
> irb(main):004:1> include X
> irb(main):005:1> end
> => Object
> irb(main):006:0> b = Object.superclass.object_id
> => -1073527798
> irb(main):007:0> a == b
> => true
>
> The information may be right or outdated but it does not necessarily
> help users of the language to understand how Ruby works.
>

My observation too has been that this so-called anonymous class is not
to be found via the :superclass method and I have already clarified that
in the document as:

-------------------------------------------------------------------
This diagram is not entirely accurate because although Anonclass appears
to become superclass of Someclass, just by the virtue of inclusion of
module Mod,  Anonclass is not returned when you do Someclass.superclass.
-------------------------------------------------------------------

But if methods were only to be defined on class objects, I am not sure
where the included module methods would come from without disturbing
inheritance chain of classes.

Any MRI experts -- how does it _really_ happen?
And how about JRuby/Rubinius?
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2013-03-14 15:49
(Received via mailing list)
On Thu, Mar 14, 2013 at 3:14 PM, Kedar Mhaswade <lists@ruby-forum.com>
wrote:
> Robert Klemme wrote in post #1101602:
>> On Thu, Mar 14, 2013 at 2:42 PM, Kedar Mhaswade <lists@ruby-forum.com>
>> wrote:

> module Mod,  Anonclass is not returned when you do Someclass.superclass.
> -------------------------------------------------------------------
>
> But if methods were only to be defined on class objects, I am not sure
> where the included module methods would come from without disturbing
> inheritance chain of classes.

You could model it like this: every class has a list of included
modules which is initially empty. Every time a module is included
which is not included in this class or any super class it is prepended
to the list.  Method lookup starts with the class itself, then
proceeds through the list of modules of this class and then proceeds
in the same way in the superclass; the process is stopped when the
first matching method is found.  If not matching method is found the
lookup process starts again with name "method_missing". (That process
with end in class BasicObject which has a definition of
#method_missing.)

> Any MRI experts -- how does it _really_ happen?
> And how about JRuby/Rubinius?

You can look it up in the implementation - it's OSS.

Kind regards

robert
D7e150e675abb80df7659fe14e7ac0a0?d=identicon&s=25 Kedar Mhaswade (kedarmhaswade)
on 2013-03-14 16:07
Robert Klemme wrote in post #1101612:
> On Thu, Mar 14, 2013 at 3:14 PM, Kedar Mhaswade <lists@ruby-forum.com>
> wrote:
>> Robert Klemme wrote in post #1101602:
>>> On Thu, Mar 14, 2013 at 2:42 PM, Kedar Mhaswade <lists@ruby-forum.com>
>>> wrote:
>
>> module Mod,  Anonclass is not returned when you do Someclass.superclass.
>> -------------------------------------------------------------------
>>
>> But if methods were only to be defined on class objects, I am not sure
>> where the included module methods would come from without disturbing
>> inheritance chain of classes.
>
> You could model it like this: every class has a list of included
> modules which is initially empty. Every time a module is included
> which is not included in this class or any super class it is prepended
> to the list.  Method lookup starts with the class itself, then
> proceeds through the list of modules of this class and then proceeds
> in the same way in the superclass; the process is stopped when the
> first matching method is found.  If not matching method is found the
> lookup process starts again with name "method_missing". (That process
> with end in class BasicObject which has a definition of
> #method_missing.)

But ... I thought a decision had already been made -- any method
definition is to occur only on a class object. If that assumption is not
true and method definitions can occur on modules, then yes, other
implementation choices exist.

>
>> Any MRI experts -- how does it _really_ happen?
>> And how about JRuby/Rubinius?
>
> You can look it up in the implementation - it's OSS.

Thanks! I guess I will need to do that.

>
> Kind regards
>
> robert
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (robert_k78)
on 2013-03-14 17:39
(Received via mailing list)
On Thu, Mar 14, 2013 at 4:07 PM, Kedar Mhaswade <lists@ruby-forum.com>
wrote:
>>> But if methods were only to be defined on class objects, I am not sure
>> lookup process starts again with name "method_missing". (That process
>> with end in class BasicObject which has a definition of
>> #method_missing.)
>
> But ... I thought a decision had already been made -- any method
> definition is to occur only on a class object. If that assumption is not
> true and method definitions can occur on modules, then yes, other
> implementation choices exist.

They *do* - from perspective of a language user.  I would try to
cleanly separate the language from implementation details.  That will
make understanding for newcomers much easier.

Cheers

robert
This topic is locked and can not be replied to.