[EVALUATION] - E03b - The Ruby Object Model

[EVALUATION] - E03 - jamLang Evaluation Case Applied to Ruby
http://groups-beta.google.com/group/comp.lang.ruby/msg/412943e7c6ed6968

···

-

In the above thread, I had some problems with the Ruby Object Model.

I currently try to create an UML diagramm, to add this to the evaluation result:

http://lazaridis.com/case/lang/ruby.html

-

The existing documentation seems at least missleading, if not wrong:

-

cmd:> ri Class

"Classes, modules, and objects are interrelated. In the diagram that
follows, the arrows represent inheritance, and the parentheses
meta-classes. All metaclasses are instances of the class `Class'."

                           +------------------+
                           > >
             Object---->(Object) |
              ^ ^ ^ ^ |
              > > > > >
              > > +-----+ +---------+ |
              > > > > >
              > +-----------+ | |
              > > > > >
       +------+ | Module--->(Module) |
       > > ^ ^ |
  OtherClass-->(OtherClass) | | |
                             > > >
                           Class---->(Class) |
                             ^ |
                             > >
                             +----------------+

-

this can be drawn like this:

          otherClass--->(OtherClass)
                 > >
                 v v
              Object--->(Object)
                 ^ ^^
                 > >>
                 > / |
                 > / |
                 > / |
                 > / |
              Module--->(Module)
                 ^ / ^
                 > / |
                 >/ |
               Class---->(Class)

-

i've played within IRB, but:

I cannot access any of the metaclasses

the same in the documentation: no metaclasses

-

Any suggestions / clarifications?

..

--
http://lazaridis.com

The existing documentation seems at least missleading, if not
wrong:

It's neither misleading nor wrong. It is complex.

this can be drawn like this:

i've played within IRB, but:
I cannot access any of the metaclasses
the same in the documentation: no metaclasses

  puts Class.id # => 20927668
  puts class << Class; self.id; end # => 20927632
  puts Object.id # => 20927692
  puts class << Object; self.id; end # => 20927656

The class "Class" has an object ID that is different than its
metaclass. The same with class "Object". Objects, too, can have
metaclasses, like:

  foo = Object.new
  puts foo.id # => 22734748
  puts class << foo; self.id; end # => 22725040

I've modified your diagram; ocObject* is an instance of otherClass,
and the (ocObject)* metaclass is the metaclass for this instance,
and it is a different metaclass than any other instance of
otherClass.

    ocObject*---->(ocObject)*
           > >
           > >
           v v
    otherClass--->(OtherClass)
           > >
           > >
           v v
        Object--->(Object)
           ^ ^^
           > >>
           > / |
           > / |
           > / |
           > / |
        Module--->(Module)
           ^ / ^
           > / |
           >/ |
         Class---->(Class)

-austin

···

On Apr 5, 2005 8:34 AM, Ilias Lazaridis <ilias@lazaridis.com> wrote:
--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

First it would appear that your repositioned diagram has an arrow
misdirected --the arrow from Class to (Object). A Class is an Object so
it should be the other way around.

Secondly, there are a number of ways to access metaclasses. Try,

  class Object
    class << self
      # (Object)
    end
  end

Substitute Class, Module or OtherClass for Object. They all should
work. Other means:

  class Object
    def Object.a_method
      # this will be a method of metaclass
    end
    def self.another_method
      # so will this
    end
  end

Realize that a classes' metaclass is the same formalism as an object's
singleton class.

Ilias Lazaridis a écrit :
> [snip]

I cannot access any of the metaclasses

the same in the documentation: no metaclasses

-

Any suggestions / clarifications?

.

Most of the time, everything goes in ruby as if there weren't any kind of metaclasses. For exemple, you cannot explicitely create your own metaclasses:

class MyMetaClass < Class
end

It raises the exception:
metaclass.rb:1: can't make subclass of Class (TypeError)

Instead of thinking in metaclasses, everything goes as if you were asked to think in terms of singleton methods. (this has nothing to do with the Singleton Pattern)

class MyClass
  def method
   puts "normal method"
  end
  def self.method
   puts "singleton method or metaclass method?"
  end
end

MyClass.new.method
# => Normal method

MyClass.method
# => singleton method or metaclass method?

p MyClass.singleton_methods
# => ["method"]

class Foo
  def test
   puts "instance method"
  end
end

foo = Foo.new

foo.test
# => instance method

class << foo
  def test
   puts "singleton method"
  end
end

# singleton methods have precedence over instance method
foo.test
# => singleton method

p foo.singleton_methods
# => ["test"]

···

--
Lionel Thiry

[... ASCII art elided ...]

Umm ... I think you have the arrow between Class and (Object) pointing the
wrong direction.

I've drawn a quasi-UML diagram for the above. You can find it here:
http://onestepback.org/images/rubyobjects.png

I've included a singleton object as well. I'm not sure if the singleton class
gets its own metaclass or shares the same meta class with its superclass.

Comments are welcome ... I'll update it if needed.

···

On Tuesday 05 April 2005 08:34 am, Ilias Lazaridis wrote:

this can be drawn like this:

--
-- Jim Weirich jim@weirichhouse.org http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)

Ilias Lazaridis wrote:

[EVALUATION] - E03 - jamLang Evaluation Case Applied to Ruby
http://groups-beta.google.com/group/comp.lang.ruby/msg/412943e7c6ed6968

-

In the above thread, I had some problems with the Ruby Object Model.

I currently try to create an UML diagramm, to add this to the evaluation result:

http://lazaridis.com/case/lang/ruby.html

-

The existing documentation seems at least missleading, if not wrong:

the documentation given via "ri Class" is definitely wrong.

I am wondering with which material the ruby development team works.

···

cmd:> ri Class

"Classes, modules, and objects are interrelated. In the diagram that
follows, the arrows represent inheritance, and the parentheses
meta-classes. All metaclasses are instances of the class `Class'."

                          +------------------+
                          > >
            Object---->(Object) |
             ^ ^ ^ ^ |
             > > > > >
             > > +-----+ +---------+ |
             > > > > >
             > +-----------+ | |
             > > > > >
      +------+ | Module--->(Module) |
      > > ^ ^ |
OtherClass-->(OtherClass) | | |
                            > > >
                          Class---->(Class) |
                            ^ |
                            > >
                            +----------------+

-

this can be drawn like this:

         otherClass--->(OtherClass)
                > >
                v v
             Object--->(Object)
                ^ ^^
                > >>
                > / |
                > / |
                > / |
                > / |
             Module--->(Module)
                ^ / ^
                > / |
                >/ |
              Class---->(Class)

-

i've played within IRB, but:

I cannot access any of the metaclasses

the same in the documentation: no metaclasses

-

Any suggestions / clarifications?

.

--
http://lazaridis.com

Ilias Lazaridis wrote:

[EVALUATION] - E03 - jamLang Evaluation Case Applied to Ruby
http://groups-beta.google.com/group/comp.lang.ruby/msg/412943e7c6ed6968

-

In the above thread, I had some problems with the Ruby Object Model.

I currently try to create an UML diagramm, to add this to the evaluation result:

http://lazaridis.com/case/lang/ruby.html

-

The existing documentation seems at least missleading, if not wrong:

the documentation given via "ri Class" is definitely wrong.

I am wondering with which material the ruby development team works.

···

cmd:> ri Class

"Classes, modules, and objects are interrelated. In the diagram that
follows, the arrows represent inheritance, and the parentheses
meta-classes. All metaclasses are instances of the class `Class'."

                          +------------------+
                          > >
            Object---->(Object) |
             ^ ^ ^ ^ |
             > > > > >
             > > +-----+ +---------+ |
             > > > > >
             > +-----------+ | |
             > > > > >
      +------+ | Module--->(Module) |
      > > ^ ^ |
OtherClass-->(OtherClass) | | |
                            > > >
                          Class---->(Class) |
                            ^ |
                            > >
                            +----------------+

-

this can be drawn like this:

         otherClass--->(OtherClass)
                > >
                v v
             Object--->(Object)
                ^ ^^
                > >>
                > / |
                > / |
                > / |
                > / |
             Module--->(Module)
                ^ / ^
                > / |
                >/ |
              Class---->(Class)

-

i've played within IRB, but:

I cannot access any of the metaclasses

the same in the documentation: no metaclasses

-

Any suggestions / clarifications?

.

--
http://lazaridis.com

Ilias Lazaridis wrote:

[EVALUATION] - E03 - jamLang Evaluation Case Applied to Ruby
http://groups-beta.google.com/group/comp.lang.ruby/msg/412943e7c6ed6968

-

In the above thread, I had some problems with the Ruby Object Model.

I currently try to create an UML diagramm, to add this to the evaluation result:

http://lazaridis.com/case/lang/ruby.html

-

The existing documentation seems at least missleading, if not wrong:

The documentation is wrong.

Find a clarifying diagramm here:

http://lazaridis.com/case/lang/ruby/

Please correct the relevant documentations.

···

-

sidenote:

The ruby evaluation contains still several limitations.

You can now send comments via the form:

http://lazaridis.com/case/lang/ruby/base.html

Additionally, you can send a whole evaluation via a convenient form:

http://lazaridis.com/case/lang/index.html

-

cmd:> ri Class

"Classes, modules, and objects are interrelated. In the diagram that
follows, the arrows represent inheritance, and the parentheses
meta-classes. All metaclasses are instances of the class `Class'."

                          +------------------+
                          > >
            Object---->(Object) |
             ^ ^ ^ ^ |
             > > > > >
             > > +-----+ +---------+ |
             > > > > >
             > +-----------+ | |
             > > > > >
      +------+ | Module--->(Module) |
      > > ^ ^ |
OtherClass-->(OtherClass) | | |
                            > > >
                          Class---->(Class) |
                            ^ |
                            > >
                            +----------------+

-

this can be drawn like this:

         otherClass--->(OtherClass)
                > >
                v v
             Object--->(Object)
                ^ ^^
                > >>
                > / |
                > / |
                > / |
                > / |
             Module--->(Module)
                ^ / ^
                > / |
                >/ |
              Class---->(Class)

-

i've played within IRB, but:

I cannot access any of the metaclasses

the same in the documentation: no metaclasses

-

Any suggestions / clarifications?

.

--
http://lazaridis.com

Do all instances have their own metaclass? I thought metaclasses (singleton
classes) sprang into existence only when needed to have a place to put
singleton methods.

···

On Tuesday 05 April 2005 10:05 am, Austin Ziegler wrote:

I've modified your diagram; ocObject* is an instance of otherClass,
and the (ocObject)* metaclass is the metaclass for this instance,
and it is a different metaclass than any other instance of
otherClass.

--
-- Jim Weirich jim@weirichhouse.org http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)

I've modified your diagram; ocObject* is an instance of otherClass,
and the (ocObject)* metaclass is the metaclass for this instance,
and it is a different metaclass than any other instance of
otherClass.

    ocObject*---->(ocObject)*
           > >
           > >
           v v
   otherClass---> (OtherClass)
           > >

Well, if ocObject is an instance of otherClass then you have a small
problem

svg% cat b.rb
#!/usr/local/bin/ruby
class A
   def self.a
      puts "A::a"
   end
   
   def a
      puts "A#a"
   end
end

class << a = A.new
   def a
      puts "a#a"
      super
   end
end

a.a
svg%

svg% b.rb
a#a
A#a
svg%

Guy Decoux

Trans wrote:

First it would appear that your repositioned diagram has an arrow
misdirected --the arrow from Class to (Object). A Class is an Object so
it should be the other way around.

I was not carefull whilst simplifying the diagramm.

possibly now I can understand:

          otherClass--->(OtherClass)
                 > >
                 v v
              Object--->(Object)
                 ^ |^
                 > >>
                 > / |
                 > / |
                 > / |
                 > / |
              Module--->(Module)
                 ^ / ^
                 > / |
                 >> >
                 >v |
               Class---->(Class)

Secondly, there are a number of ways to access metaclasses. Try,

  class Object
    class << self
      # (Object)
    end
  end

Substitute Class, Module or OtherClass for Object. They all should
work. Other means:

  class Object
    def Object.a_method
      # this will be a method of metaclass
    end
    def self.another_method
      # so will this
    end
  end

Realize that a classes' metaclass is the same formalism as an object's
singleton class.

I'm sorry.

I cannot extract any essence.

[I have reviewed all the other answer, too - but now I am even more confused now. will give it tomorrow another try]

..

···

--
http://lazaridis.com

Hmm, the rigor of the interpreter here is somewhat loose. You can
subclass Class, just not as you tried.

MyMetaClass = Class.new Class
MyMetaClass.ancestors
# => [MyMetaClass, Class, Module, Object, Kernel]

This works just fine. However, it's not too consistent altogether...

Csaba

···

On 2005-04-05, Lionel Thiry <lthiryidontwantspam@skynetnospam.be> wrote:

Most of the time, everything goes in ruby as if there weren't any kind of
metaclasses. For exemple, you cannot explicitely create your own metaclasses:

class MyMetaClass < Class
end

It raises the exception:
metaclass.rb:1: can't make subclass of Class (TypeError)

Ilias Lazaridis <ilias@lazaridis.com> writes:

Ilias Lazaridis wrote:

[EVALUATION] - E03 - jamLang Evaluation Case Applied to Ruby
http://groups-beta.google.com/group/comp.lang.ruby/msg/412943e7c6ed6968
-
In the above thread, I had some problems with the Ruby Object Model.
I currently try to create an UML diagramm, to add this to the
evaluation result:
http://lazaridis.com/case/lang/ruby.html
-
The existing documentation seems at least missleading, if not wrong:

the documentation given via "ri Class" is definitely wrong.

I am wondering with which material the ruby development team works.

We call it... The Source.

···

http://lazaridis.com

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

That's my understanding, too. But since you can't look at a
metaclass without instantiating it, the minor sleight of hand that I
performed above is (IMO) acceptable.

Consider:

  a = Object.new; b = Object.new
  puts a.id, b.id
# 22756396
# 22756384
  class << a; puts self.id; end; class << b; puts self.id; end
# 22738408
# 22738396

In effect, all instances have their own metaclass. As an
implementation detail, though, they aren't instantiated until they
are needed. I'm not sure that there's a meaningful difference
between the lazy instantiation and constant instantiation from the
Ruby programmer's point of view -- unless you're doing something
really freaky with AST parsers :wink:

-austin

···

On Apr 5, 2005 12:48 PM, Jim Weirich <jim@weirichhouse.org> wrote:

On Tuesday 05 April 2005 10:05 am, Austin Ziegler wrote:

I've modified your diagram; ocObject* is an instance of
otherClass, and the (ocObject)* metaclass is the metaclass for
this instance, and it is a different metaclass than any other
instance of otherClass.

Do all instances have their own metaclass? I thought metaclasses
(singleton classes) sprang into existence only when needed to have
a place to put singleton methods.

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

> I've modified your diagram; ocObject* is an instance of otherClass,
> and the (ocObject)* metaclass is the metaclass for this instance,
> and it is a different metaclass than any other instance of
> otherClass.

> ocObject*---->(ocObject)*
> > >
> > >
> v v
> otherClass---> (OtherClass)
> > >
Well, if ocObject is an instance of otherClass then you have a small
problem

You're right. I just copied a part of the diagram without thinking.

         ocInstance---->(ocInstance)
                >
                >
                v
         otherClass---->(OtherClass)
                > >
                > >
                v v
             Object---->(Object)--+
                ^ ^ |
                > > >
                > > >
                > > >
                > > >
                > > >
             Module---->(Module) |
                ^ ^ |
                > > >
                > > >
              Class---->(Class) |
                ^ |

···

On Apr 5, 2005 1:08 PM, ts <decoux@moulon.inra.fr> wrote:
                > >
                +-----------------+

I think that captures the instance case a bit better.

-austin
--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

"Csaba Henk" <csaba@phony_for_avoiding_spam.org> schrieb im Newsbeitrag
news:slrnd5d5vm.crg.csaba@ms0.math.ucalgary.ca...

> Most of the time, everything goes in ruby as if there weren't any kind

of

> metaclasses. For exemple, you cannot explicitely create your own

metaclasses:

>
> class MyMetaClass < Class
> end
>
> It raises the exception:
> metaclass.rb:1: can't make subclass of Class (TypeError)

Hmm, the rigor of the interpreter here is somewhat loose. You can
subclass Class, just not as you tried.

MyMetaClass = Class.new Class
MyMetaClass.ancestors
# => [MyMetaClass, Class, Module, Object, Kernel]

This works just fine. However, it's not too consistent altogether...

The question is, what does one gain by subclassing Class? You cannot
create instances (i.e. classes) of it:

Foo = MyMetaClass.new

TypeError: wrong instance allocation
        from (irb):5:in `new'
        from (irb):5

Foo = MyMetaClass.allocate

TypeError: wrong instance allocation
        from (irb):6:in `allocate'
        from (irb):6

Cheers

    robert

···

On 2005-04-05, Lionel Thiry <lthiryidontwantspam@skynetnospam.be> wrote:

Christian Neukirchen wrote:

Ilias Lazaridis <ilias@lazaridis.com> writes:

Ilias Lazaridis wrote:

[EVALUATION] - E03 - jamLang Evaluation Case Applied to Ruby
http://groups-beta.google.com/group/comp.lang.ruby/msg/412943e7c6ed6968
-
In the above thread, I had some problems with the Ruby Object Model.
I currently try to create an UML diagramm, to add this to the
evaluation result:
http://lazaridis.com/case/lang/ruby.html
-
The existing documentation seems at least missleading, if not wrong:

the documentation given via "ri Class" is definitely wrong.

I am wondering with which material the ruby development team works.

We call it... The Source.

Ok, now I understand.

..

···

--
http://lazaridis.com

        ocInstance---->(ocInstance)
               >
               >
               v
        otherClass---->(OtherClass)

Well, write it like this

         ocInstance-->(ocInstance)
                        /
                       /
                      /
                     /
                    /
                   /
                  /
                 /
                v
         otherClass-->(OtherClass)

and don't say that ruby create the "singleton" class for ocInstance, only
when it need it :slight_smile:

Guy Decoux

That's good to know, but this question is another question. What I was
wandering about is that why it is so that you can't subclass Class if
you use the syntax "class Foo < Bar" but you can do it as
"Foo = Class.new Bar".

Considering the effectiveness of subclassing class: most of this stuff
you'd want to achieve this way can be done by just subclassing Module.
You'll be free to implement "new" as you want (although you can't use
"super" in this definiton, you can do "o = Object new; o.extend Foo").

Csaba

···

On 2005-04-08, Robert Klemme <bob.news@gmx.net> wrote:

"Csaba Henk" <csaba@phony_for_avoiding_spam.org> schrieb im Newsbeitrag
news:slrnd5d5vm.crg.csaba@ms0.math.ucalgary.ca...

On 2005-04-05, Lionel Thiry <lthiryidontwantspam@skynetnospam.be> wrote:
> Most of the time, everything goes in ruby as if there weren't any kind

of

> metaclasses. For exemple, you cannot explicitely create your own

metaclasses:

>
> class MyMetaClass < Class
> end
>
> It raises the exception:
> metaclass.rb:1: can't make subclass of Class (TypeError)

Hmm, the rigor of the interpreter here is somewhat loose. You can
subclass Class, just not as you tried.

MyMetaClass = Class.new Class
MyMetaClass.ancestors
# => [MyMetaClass, Class, Module, Object, Kernel]

This works just fine. However, it's not too consistent altogether...

The question is, what does one gain by subclassing Class? You cannot
create instances (i.e. classes) of it: