virtual metaclasses explanation

Discussion in 'Ruby' started by angel.of.north@googlemail.com, May 24, 2007.

  1. Guest

    I am getting a bit weighed down at this moment by looking under the
    bonnet a bit too much, but in figure 24.2 in Dave Thomas Pragmatic
    Programming,
    classes and objects is is unclear how the metaclass acquires its
    additional method as strings.
    Dave Rhomas says that the metaclass will inherit all it methods from
    its corresponding proper class.

    1. Do all inheritance chains and all objects have a homologue
    metaclass at all times, which are behind the scenes?
    2. Do a chain of metaclasses spontaneously appear at the moment
    when a class is used as a receiver : so to be used to call a method
    inside of a parentclass?
    3. How can a metaclass contain more methods than its corresponding
    class has. Can you give an example of the code in the next addition?
    4. Which is searched first in the inheritance chain. methods in
    the proper parents, or methods in the meta parents?
    5. If a method is found is the search stopped even though another
    method with the same name might exist in a parallel chain?

    I have made some written notes as I went along which might interest
    you. It is useful to know how the reader is progressing.

    def ClassA
    def initialize
    #some code
    end
    end

    def ClassB
    def ClassA.methodX
    #code
    end
    def ClassB.methodY
    #code
    end
    end



    both work.
    Is this a good idea to define a class method within a different
    class? is this the point of OO or is it bad programming style?

    Andy Hunt says

    It depends. In general, that's probably bad style as you're likely
    violating the encapsulation of ClassA.

    Regards,

    /\ndy

    \newpage

    class ClassA
    def initialize
    puts "something classA"
    end
    end

    class ClassC
    def initialize
    puts "someting classC"
    end
    def methodY
    puts "beach balls"
    end
    end



    class ClassB < ClassC
    def methodY
    super
    puts "something ClassB.methodY"
    end
    end

    test = ClassA.new
    stuart = ClassB.new
    puts stuart.methodY




    stuart = ClassB.methodY

    or

    stuart = ClassB.new
    stuart.methodY

    stuart is an object which is initialized of the class method as
    ClassB.new which is mostly defined as an ordinary method called
    initialize inside of and at the beginnning of the class as ClassB

    Sometimes the object as stuart will be referred by as the receiver if
    a method within the class by which the object as stuart is defined, is
    called after the object name as stuart. i.e stuart.methodY. Stuart is
    reffered by as the receiver so to indicate that the class of the
    object as stuart, which in this case is the class as ClassB, contains
    a method which the object as stuart may access ; i.e stuart.methodY.

    The object as Stuart is related by the class as ClassB. The object as
    stuart is of the class as ClassB. The word as related means the same
    as the word as linked within this context.

    Each class may be part of an inheritance chain.

    But the class as classB may also be considered an object. Therefore
    the class as classB itself may also be used as a receiver. e.g.

    ClassB.methodZ

    where the method as Z is defined within the class as ClassC : which is
    the parentclass of ClassB.
    or
    where the method as Z is defined within the class as ClassB' : which
    is a virtual class of ClassB.
    Because ClassB' is the virtual class of ClassB and Class B is also the
    subclass of ClassC, another virtual class as ClassC is established to
    be the virtual parentclass of the virual class as ClassB'. None of
    these virtual classes are supposed to be immediately visible. The
    virtual class as ClassB' will contain all the methods of ClassB and
    this pattern is repeated through the parallel inheritance chain.







    > > QUESTION
    > > I'm trying to understand classes and objects. The Pick axe book
    > > describes the method as "once" inside of the class as Date, and how this method is defined
    > > by using the object singleton technique as "class << self". Actually
    > > the class as Date uses this method at several places. Until I saw the class as Date I thought that the
    > > reason by this singleton techinique was to add and replace methods inside of classes at such circumstances when you
    > > don't have convenient ways to access by the class definition ; so I conclude that basically,
    > > one should use this singleton technique when it's not your class which you need to enhance. But the fact
    > > that the class as Date uses this method several times indicates there is another reason to
    > > use it.


    which is derived from
    comp.lang.ruby August 9 2005
    Kelly Felkins wrote:
    > > I'm trying to understand classes and objects. The Pick axe book
    > > points out the "once" method in class Date and how it is defined
    > > using the object singleton technique of "class << self". Actually
    > > Date uses this in several places. Up until seeing Date I thought the
    > > reason for this idiom was to add/replace methods in classes *when you
    > > don't have convenient access to the class definition* -- basically,
    > > use this when it's not your class you need to enhance. But the fact
    > > that Date uses it several times indicates there is another reason to
    > > use it.



    ANSWER

    As you guessed, the reasons are different: typically you use "class
    <<something...end" if you have to define several methods or if you
    need a
    class context for things to work (for example "alias").

    These are equivalent:

    class Foo
    class <<self
    def m1() "foo" end
    end


    class <<Foo
    def m2() "foo" end
    end


    def self.m3() "foo" end
    def Foo.m4() "foo" end
    end


    class <<Foo
    def m5() "foo" end
    end


    def Foo.m6() "foo" end


    x = Foo
    def x.m7() "foo" end


    class <<x
    def m8() "foo" end
    end


    Now you have methods m1 to m8 as instance methods of Foo. You can do
    Foo.m1(), Foo.m2 etc.

    More technically, with class <<something ... end you make definition
    for
    the so called "singleton class" the class instance responsible for the
    single instance at hand (which happens to be a class object in this
    case;
    but you can repeat the example above with any object instead of Foo).
    You
    cannot create instances from this class:


    irb(main):001:0> class Foo
    irb(main):002:1> p new
    irb(main):003:1> end
    #<Foo:0x10192d58>
    => nil
    irb(main):004:0> class <<Foo
    irb(main):005:1> p new
    irb(main):006:1> end
    TypeError: can't create instance of virtual class
    from (irb):5:in `new'
    from (irb):5



    -- No virus found in this incoming message. Checked by AVG Free
    Edition. Version: 7.5.467 / Virus Database: 269.7.7/816 - Release
    Date: 23/05/2007 15:59
     
    , May 24, 2007
    #1
    1. Advertising

  2. On 5/24/07, <> wrote:
    > I am getting a bit weighed down at this moment by looking under the
    > bonnet a bit too much, but in figure 24.2 in Dave Thomas Pragmatic
    > Programming,
    > classes and objects is is unclear how the metaclass acquires its
    > additional method as strings.
    > Dave Rhomas says that the metaclass will inherit all it methods from
    > its corresponding proper class.


    I don't have the time to digest your long thread which followed, but
    I'll try to address these questions.

    > 1. Do all inheritance chains and all objects have a homologue
    > metaclass at all times, which are behind the scenes?


    In ruby metaclasses are singleton classes of classes. Just as a class
    holds the table used to find the methods of its instances, the
    metaclass holds the table used to find methods for its sole instance
    i.e. the class.

    The singleton class which serves as the metaclass of a class is
    created when the class is created. This is done internally by the
    Ruby interpreter.

    While object's don't have metaclasses they can have singleton classes,
    which are created when needed, e.g. when you do something like

    a = "abc"
    b = "def"

    def a.method;...;end # singleton class for the object referenced by
    a is created now
    class <<b #singleton class for the object referenced by b is created now
    ...
    end

    > 2. Do a chain of metaclasses spontaneously appear at the moment
    > when a class is used as a receiver : so to be used to call a method
    > inside of a parentclass?


    No, as I just said, metaclasses are created along with their
    corresponding class. The metaclass' superclass is set to the
    metaclass of the classes superclass. This is one difference between
    singleton classes of objects and singleton classes used as
    metaclasses. The later can have subclasses, while the former cannot.

    Normal object singleton classes have their internal superclass set to
    the original class of the object.

    Note that I'm using superclass and class here to describe the internal
    relationship. Ruby's class and superclass methods don't always give a
    true picture when singleton/metaclasses are involved. I personally
    think of the class-like objects linked together with the superclass
    field as a behavior chain since it's used to implement the behaviour
    of one or more objects.

    > 3. How can a metaclass contain more methods than its corresponding
    > class has. Can you give an example of the code in the next addition?


    The number of methods in the class and the number of methods in the
    metaclass is completely independent, for example, look at the
    following and compare it to what I said in reponse to question #1

    class MyClass

    def initialize # This defines the initialize method in MyClass which
    # Like all such methods are available to INSTANCEs
    # of the class, and its subclasses
    #
    end

    def method1 # another instance method
    end

    def MyClass.class_method # This defines a class method in the
    # singleton class of MyClass (i.e. the metaclass)
    # which is available to instances of the
    metaclass and
    # its subclasses
    end

    def self.class_method_2 # This adds another class method, it's
    # Just a different syntax for the last
    form of definition
    # since within the scope of a class
    definition, self is
    # bound to that class
    end

    class << self # or equivalently class << MyClass
    # Now we are in an inner scope, that of MyClass' metaclass
    def class_method_3 # So this also becomes a class method
    # of MyClass
    end
    end

    So MyClass has two instance methods (plus what it inherits from
    Object) and three class methods (plus what the metaclass inherits from
    Object's metaclass.

    As a related note, when a class includes a Module, another kind of
    virtual class is inserted between the class and it's superclass. This
    virtual class (or I_Class) looks like a class but has a pointer to the
    method table of the module instead of having its own table. This
    lets modules appear in different behavior chains and lets those
    including them see updates to the module when they are made. There
    are some other fields of the module which are also copied, but I'm not
    going to mention them here since they aren't relevant and might
    confuse.

    > 4. Which is searched first in the inheritance chain. methods in
    > the proper parents, or methods in the meta parents?


    There's no cross over at all. When finding a method for an object,
    Ruby gets the head of what I called the behavior chain. For a normal
    object with no singleton class, this will be the class, For an object
    with a singleton class this will be the singleton class. If the
    method is found, then it's used, if not the next class-like thing in
    the behavior chain is examined and so forth. The keyword super makes
    the search start in the next link in the behavior chain after the one
    in which the current method was found.

    So if you're invoking a method on a normal object, no metaclasses will
    be on the chain. If you are invoking a method on a class, then the
    behavior chain will consist of metaclasses, except that the superclass
    of Object's metaclass is Class. If you think about this hard enough it
    makes sense, since the instance methods of Class are for use by
    classes.

    So if we have

    class B
    ...
    end

    b = B.new
    b.to_s

    The search goes:

    B -> Object -> (I_Class wrapper for Kernel)
    the last is because Object includes Kernel

    and
    B.new
    the search goes

    (singleton of B) -> (singleton of Object) -> Class -> Module ->
    Object -> (I_Class wrapper for Kernel)

    > 5. If a method is found is the search stopped even though another
    > method with the same name might exist in a parallel chain?


    As I just described, the parallel chain is irrelevant, it isn't
    considered at all.

    HTH
    --
    Rick DeNatale

    My blog on Ruby
    http://talklikeaduck.denhaven2.com/
     
    Rick DeNatale, May 24, 2007
    #2
    1. Advertising

  3. Guest

    Thankyou for replying at such length. I am sure that what you have
    explained I will understand properly soon. I think that this post
    deserves some web links.

    David R
     
    , May 24, 2007
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Stephan Diehl

    question about metaclasses

    Stephan Diehl, Jun 30, 2003, in forum: Python
    Replies:
    2
    Views:
    338
    Stephan Diehl
    Jun 30, 2003
  2. Simon Burton

    metaclasses

    Simon Burton, Jul 28, 2003, in forum: Python
    Replies:
    5
    Views:
    397
    Simon Burton
    Jul 30, 2003
  3. Mike C. Fletcher

    Metaclasses presentation slides available...

    Mike C. Fletcher, Aug 28, 2003, in forum: Python
    Replies:
    3
    Views:
    339
    Alex Martelli
    Aug 29, 2003
  4. Simon Burton

    metaclasses for type comparison

    Simon Burton, Sep 11, 2003, in forum: Python
    Replies:
    5
    Views:
    310
    David Eppstein
    Sep 11, 2003
  5. Santiago Aguiar

    AOP and metaclasses

    Santiago Aguiar, Feb 20, 2004, in forum: Python
    Replies:
    2
    Views:
    329
    John Roth
    Feb 20, 2004
Loading...

Share This Page