Forum: Ruby THE CLASS/OBJECT CHICKEN-AND-EGG PARADOX

Posted by Xavier R. (arup_r)
on 2013-02-20 21:33
Hi,


Anyone out there could help me to understand the "THE CLASS/OBJECT
CHICKEN-AND-EGG PARADOX". I am a newbie to this topic. The more I am
trying to get it making me confused. So anyway to get this one easily.


Also another topic making me confused "instance of class" and "instance
of object" - when the second one is pretty clear,but the first one still
not clear.

Thanks in advance.
Posted by Peter Hickman (Guest)
on 2013-02-20 21:48
(Received via mailing list)
Google is your friend. Always at least try and Google something before
coming here.

Guess what I found when I googled the subject of this post (other than 
this
post - damn Google is fast)?

The stackoverflow answer is good.
Posted by Matt Mongeau (halogenandtoast)
on 2013-02-20 21:49
(Received via mailing list)
Maybe you could provide more detail about what you are confused about. 
To
help clarify the second part.

Doing

class Foo
end

is similar to doing

Foo = Class.new

There you can see Foo is an instance of Class. Everything in ruby is 
object
(so to say), so Foo is still an instance of an object.

foo = Foo.new

This is an instance of Object, but not an instance of Class.

Hope this helps.


2013/2/20 Xavier R. <lists@ruby-forum.com>
Posted by Xavier R. (arup_r)
on 2013-02-20 21:57
Matt Mongeau wrote in post #1098058:
> Maybe you could provide more detail about what you are confused about.

The class Class is an instance of itself; that is, it’s a Class object. 
And there’s more.
Remember the class Object? Well, Object is a class—but classes are 
objects. So,Object is an object. And Class is a class. And Object is a 
class, and Class is an object.

Which came first? How can the class Class be created unless the class 
Object
already exists? But how can there be a class Object (or any other class) 
until there’s a class Class of which there can be instances?

This is a paragraph taken from David A. Black's book.The above paragraph 
made me too confused.

Thanks
Posted by Matt Mongeau (halogenandtoast)
on 2013-02-20 22:47
(Received via mailing list)
It's not really a paradox. Take for example
irb(main):001:0> a = []
=> []
irb(main):002:0> a << a
=> [[...]]

How can a contain itself? The answer is that it's a reference. This is 
the
case for Class, the internal structure for determining the class of an
object holds a reference to itself

290  struct RBasic {
 291      unsigned long flags;
 292      VALUE klass;
 293  };

See how klass is a VALUE, in the c-land VALUE is the equivalent of an
Object, so Class is an object where klass is set to point to itself.

You wouldn't really be able to create a class whose superclass is itself 
in
Ruby (at least nothing I can think of). I think this is often where 
people
get confused, the c implementation is not under the same restrictions as
the ruby implementation.

Object is in a similar situation:

295  struct RObject {
 296      struct RBasic basic;
 297      struct st_table *iv_tbl;
 298  };

You can see that Object has an RBasic struct inside of it. In class.c 
you
can see that these cases are handled in a special way.

375     rb_cObject = boot_defclass("Object", rb_cBasicObject);
376     rb_cModule = boot_defclass("Module", rb_cObject);
377     rb_cClass =  boot_defclass("Class",  rb_cModule);
Posted by Xavier R. (arup_r)
on 2013-02-20 23:03
Matt Mongeau wrote in post #1098076:
> It's not really a paradox. Take for example
> irb(main):001:0> a = []
> => []
> irb(main):002:0> a << a
> => [[...]]
>

Is it possible to give some small ruby code in-contrast with C - code 
for better understanding.

That might clear the picture more clearly.


Thanks
Posted by Matt Mongeau (halogenandtoast)
on 2013-02-20 23:19
(Received via mailing list)
What would you want the code to show?


2013/2/20 Xavier R. <lists@ruby-forum.com>
Posted by Xavier R. (arup_r)
on 2013-02-20 23:24
Matt Mongeau wrote in post #1098087:
> What would you want the code to show?
>
>
> 2013/2/20 Xavier R. <lists@ruby-forum.com>


Yes! Ruby code to understand the things against the C one's.
Posted by Ryan Davis (Guest)
on 2013-02-20 23:35
(Received via mailing list)
On Feb 20, 2013, at 12:33 , Xavier R. <lists@ruby-forum.com> wrote:

> Anyone out there could help me to understand the "THE CLASS/OBJECT
> CHICKEN-AND-EGG PARADOX". I am a newbie to this topic. The more I am
> trying to get it making me confused. So anyway to get this one easily.

PRE-CHICKEN! Wait... what's the question?
Posted by Joel Pearson (virtuoso)
on 2013-02-20 23:36
Matt Mongeau wrote in post #1098076:
> It's not really a paradox. Take for example
> irb(main):001:0> a = []
> => []
> irb(main):002:0> a << a
> => [[...]]

irb(main):003:0> a.flatten!
ArgumentError: tried to flatten recursive array
        from (irb):3:in `flatten!'
        from (irb):3
        from C:/Ruby193/bin/irb:12:in `<main>'

Ha! I bet whoever wrote that ( Matz, presumably? ) was shaking his head 
and thinking "Well this is one error message no sane programmer will 
ever see." I'd never have seen that as a possibility.
Posted by Matt Mongeau (halogenandtoast)
on 2013-02-20 23:40
Joel Pearson wrote in post #1098100:
> Matt Mongeau wrote in post #1098076:
>> It's not really a paradox. Take for example
>> irb(main):001:0> a = []
>> => []
>> irb(main):002:0> a << a
>> => [[...]]
>
> irb(main):003:0> a.flatten!
> ArgumentError: tried to flatten recursive array
>         from (irb):3:in `flatten!'
>         from (irb):3
>         from C:/Ruby193/bin/irb:12:in `<main>'
>
> Ha! I bet whoever wrote that ( Matz, presumably? ) was shaking his head
> and thinking "Well this is one error message no sane programmer will
> ever see." I'd never have seen that as a possibility.

For more object reference shenanigans please enjoy

irb(main):005:0> h = {}
=> {}
irb(main):006:0> h[h] = h
=> {{...}=>{...}}
irb(main):007:0> h.to_a
=> [[{{...}=>{...}}, {{...}=>{...}}]]
Posted by Matt Mongeau (halogenandtoast)
on 2013-02-20 23:46
Xavier R. wrote in post #1098091:
> Matt Mongeau wrote in post #1098087:
>> What would you want the code to show?
>>
>>
>> 2013/2/20 Xavier R. <lists@ruby-forum.com>
>
>
> Yes! Ruby code to understand the things against the C one's.

Something like this?

水/tmp‹1.9.3-p374›$ irb
irb(main):001:0> class XObject
irb(main):002:1> def initialize klass
irb(main):003:2> @klass = klass
irb(main):004:2> end
irb(main):005:1> attr_reader :klass
irb(main):006:1> end
=> nil
irb(main):007:0> XObject = XObject.new(XObject)
(irb):7: warning: already initialized constant XObject
=> #<XObject:0x007fdddc9887c8 @klass=XObject>
irb(main):008:0> XObject.klass
=> XObject
irb(main):009:0> XObject.class
=> XObject
Posted by Stu (Guest)
on 2013-02-21 00:16
(Received via mailing list)
Xavier -

Meta-Programming Ruby is a decent book which explains a bit better on
your question. Though Blacks book is a better book for just starting
ruby it mainly is just a beginners book.

It may be helpful to understand what a Module is in ruby and how it's
used with classes in ruby's object model. Also you'll want to
investigate what a Eigenclass class is and what singleton methods are.
 Also note how ruby's reflection and method lookup syntax may always
be telling the whole truth. Mainly this has to do with scoping rules
and hidden classes as well to allow embedded languages within ruby
which can be seen in ruby's recursive style iteration syntax
methodology.

One way to visualize it outside of the repl would be to consider that
lookup begins at the instance object's receiver and moves to the right
and then up.

Showing the C code would be to see what the actual implementation is
doing. If you were to view it as a flattened set of instructions a
reference pointer would simply be a hash which simply is a two
dimensional array.

If your interested in reading ruby implemented in ruby instead of c
check out Rubinius and install pry. Rubinius is a smalltalk based vm
written in c++( iirc) at the bootstrap level and written in pure ruby
beyond that.

Of course if object based programming is new to you it's also
necessary to grok what self is and how message sending and
communication works. Consider it just the one of the many programming
models which ruby has at the end users disposal.

~Stu
Posted by Eric Christopherson (echristopherson)
on 2013-02-21 00:27
(Received via mailing list)
On Wed, Feb 20, 2013 at 5:15 PM, Stu <stu@rubyprogrammer.net> wrote:
> Rubinius is a smalltalk based vm
> written in c++( iirc) at the bootstrap level and written in pure ruby
> beyond that.

Minor nitpick: I think you're confusing MagLev, which has a Smalltalk
VM base, and Rubinius, which has an LLVM base.
Posted by Stu (Guest)
on 2013-02-21 00:50
(Received via mailing list)
Here's a simple conceptual model to think of if it seems a bit 
obfuscated.

Go to your deskop and create a folder called myfolder.

open myfolder and create a folder inside it called myfolder.

Considering your desktop is TOP level much like main() is to many
programming languages and environments. Or how Class is an abstraction
for object oriented languages what Stucts are abstracted data types to
procedural languages.

If you want to blow your mind a bit you can create an alias, shortcut,
or softlink depending on operating system to reference (or point to)
the original myfolder.

Actually I'm not sure if that's helpful. I'm better with fixing
problems that exist at a gestalt level. Maybe looking at ObjectSpace
may also give some hints (or a screen full of junk) on the
interpreters preprocessing state.

On Wed, Feb 20, 2013 at 5:27 PM, Eric Christopherson
<echristopherson@gmail.com> wrote:
> On Wed, Feb 20, 2013 at 5:15 PM, Stu <stu@rubyprogrammer.net> wrote:
>> Rubinius is a smalltalk based vm
>> written in c++( iirc) at the bootstrap level and written in pure ruby
>> beyond that.
>
> Minor nitpick: I think you're confusing MagLev, which has a Smalltalk
> VM base, and Rubinius, which has an LLVM base.

My bad. I can't install MagLev on FreeBSD. Is it worth checking out.
For extension languages I prefer these interpreters to be able to run
everywhere. I don't know how I was mislead. wikipedia mentions a short
stub on using the smalltalk bluebook but outside of using pry to
become inspired on some of the methods already in place in the
language I generally use mri and in some cases jruby. What's the use
case for maglev? Fuse ruby with squeak?

~Stu
Posted by Matt Mongeau (halogenandtoast)
on 2013-02-21 00:52
(Received via mailing list)
No he means smalltalk. The vm was heavily inspired by the vm described
on smalltalk 80

Sent from my iPhone
Posted by Love U Ruby (my-ruby)
on 2013-02-21 09:21
Stu wrote in post #1098107:
> Xavier -
>
> Meta-Programming Ruby is a decent book which explains a bit better on
> your question. Though Blacks book is a better book for just starting
> ruby it mainly is just a beginners book.

Could you tell me the black book name?

> One way to visualize it outside of the repl would be to consider that
> lookup begins at the instance object's receiver and moves to the right
> and then up.

Could you a bit explain the above concept?

Thanks
Posted by Joel Pearson (virtuoso)
on 2013-02-21 10:09
Love U Ruby wrote in post #1098153:
> Could you tell me the black book name?

It's on the first page of a simple Google search...

http://www.amazon.com/Well-Grounded-Rubyist-David-...
Posted by unknown (Guest)
on 2013-02-21 10:53
(Received via mailing list)
Love U Ruby:

Please re-read the mail chain before asking questions. The below line 
can be found in the attached mail (last paragraph).

"This is a paragraph taken from David A. Black's book."
Posted by Xavier R. (arup_r)
on 2013-02-21 19:03
In this regard please help me to understand the below :

"every object has an internal record of what class it’s an instance of, 
and the internal record inside the object Class points back to Class."

Thanks.
Posted by Matt Mongeau (halogenandtoast)
on 2013-02-21 20:23
void
Init_class_hierarchy(void)
{
    id_attached = rb_intern("__attached__");

    rb_cBasicObject = boot_defclass("BasicObject", 0);
    rb_cObject = boot_defclass("Object", rb_cBasicObject);
    rb_cModule = boot_defclass("Module", rb_cObject);
    rb_cClass =  boot_defclass("Class",  rb_cModule);

    rb_const_set(rb_cObject, rb_intern("BasicObject"), rb_cBasicObject);
    RBASIC(rb_cClass)->klass
  = RBASIC(rb_cModule)->klass
  = RBASIC(rb_cObject)->klass
  = RBASIC(rb_cBasicObject)->klass
  = rb_cClass;
}
This is exactly what is happening. You can see it builds all of these 
first AND then sets the klass AFTER they are created.

But to break it down further...

>> "every object has an internal record"

This is RBasic:
295  struct RObject {
 296      struct RBasic basic;
 297      struct st_table *iv_tbl;
 298  };
290  struct RBasic {
 291      unsigned long flags;
 292      VALUE klass;
 293  };
>> " of what class it’s an instance of,"

See how RObject has an RBasic, see how RBasic has a klass. When 
rb_cObject is first created klass is a null value, later it sets that 
value:

>> "and the internal record inside the object Class"

We're talking about RBasic again here

>> "points back to Class."

 RBASIC(rb_cClass)->klass
  = RBASIC(rb_cModule)->klass
  = RBASIC(rb_cObject)->klass
  = RBASIC(rb_cBasicObject)->klass
  = rb_cClass;
That is done there.

If you want more details about how these things work check out the 
following:

http://rhg.rubyforge.org/chapter02.html
http://rhg.rubyforge.org/chapter04.html
Posted by Xavier R. (arup_r)
on 2013-02-21 20:34
Matt Mongeau wrote in post #1098274:

You are awesome! But I am weak in C code :(. So can the same explanation 
be
made using Ruby code?


>
> If you want more details about how these things work check out the
> following:
>
> http://rhg.rubyforge.org/chapter02.html
> http://rhg.rubyforge.org/chapter04.html
Posted by Bartosz Dziewoński (matmarex)
on 2013-02-21 20:58
(Received via mailing list)
On Thu, 21 Feb 2013 20:34:46 +0100, Xavier R. <lists@ruby-forum.com> 
wrote:

> You are awesome! But weak in C code :(. So can the same explanation be
> made using Ruby code?

No. The code is in C, so obviously the explanation is for C code.
Posted by Stu (Guest)
on 2013-02-21 21:34
(Received via mailing list)
On Thu, Feb 21, 2013 at 12:03 PM, Xavier R. <lists@ruby-forum.com> 
wrote:
> In this regard please help me to understand the below :
>
> "every object has an internal record of what class its an instance of,
> and the internal record inside the object Class points back to Class."
>
> Thanks.
>

It's a formal and direct explanation of the "Everything is and
Object". In the sense of "Turtles all the way down" not "I'm my own
grandpa!".

Review the syntax and experiment in irb with class, superclass,
ancestors on your own custom classes as well as the built in types
such as array, integers, strings. See if you can figure out how to
identify the methods associated within the inheritance chain at each
level from the instance methods to the class methods to the
superclasses methods and so forth.

Good luck

~Stu
Posted by Ryan Davis (Guest)
on 2013-02-21 23:30
(Received via mailing list)
On Feb 21, 2013, at 11:34 , "Xavier R." <lists@ruby-forum.com> wrote:

> You are awesome! But weak in C code :(. So can the same explanation be
> made using Ruby code?

It is almost exactly the same with minor syntactic differences. Remove 
the rb_c's and semicolons, switch "->" to "." and you have pretty much 
the same thing in ruby.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.