[ANN] Article: Seeing Metaclasses Clearly

Discussion in 'Ruby' started by why the lucky stiff, Apr 18, 2005.

  1. I've written a very nuts+bolts article on metaclasses (aka virtual
    classes or metaobjects), since they still lurk under a shroud of fear
    and enigma.

    <http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html>

    I'm hoping this will help uncover the truth. If anything is unclear,
    please report it. Shed a light.

    Sharkin',

    _why
     
    why the lucky stiff, Apr 18, 2005
    #1
    1. Advertising

  2. why the lucky stiff

    Sascha Ebach Guest

    why the lucky stiff wrote:
    > I've written a very nuts+bolts article on metaclasses (aka virtual
    > classes or metaobjects), since they still lurk under a shroud of fear
    > and enigma.
    >
    > <http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html>
    >
    > I'm hoping this will help uncover the truth. If anything is unclear,
    > please report it. Shed a light.


    Very nice and thanks,

    would you mind using a print stylesheet so the article can be nicely
    printed out?

    Sascha Ebach
     
    Sascha Ebach, Apr 18, 2005
    #2
    1. Advertising

  3. Hi --

    On Mon, 18 Apr 2005, why the lucky stiff wrote:

    > I've written a very nuts+bolts article on metaclasses (aka virtual classes or
    > metaobjects), since they still lurk under a shroud of fear and enigma.
    >
    > <http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html>
    >
    > I'm hoping this will help uncover the truth. If anything is unclear, please
    > report it. Shed a light.


    For some reason the first 1/8 inch or so on the left are cut off on my
    browser. I don't know whether it's a CSS thing or a browser thing
    (Netscape 6). So "methods" comes out as "thods", etc.

    The tutorial itself looks good, though the terminology in this area
    continues to be a problem. My understanding is that the most general
    term is "singleton class", and that "metaclass" is a special term for
    singleton class of a Class object. (See Pickaxe, 2nd ed., p. 382.)
    So, for example, I would rename your Object#metaclass method
    #singleton_class, since it applies to all objects (as per RCR 231).

    Then there's "virtual class", which I think is the weakest and least
    useful term, certainly at a general level. The Matz paraphrase on
    p.382 suggests that virtual-ness is more a matter of implementation
    than anything language-level, which is good. I haven't checked, but
    I'm hoping the > 1.8 error messages will cease to refer to "virtual"
    classes (e.g., when you try to get at the singleton class of a
    Fixnum).


    David

    --
    David A. Black
     
    David A. Black, Apr 18, 2005
    #3
  4. why the lucky stiff wrote:

    > <http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html>
    >
    > I'm hoping this will help uncover the truth. If anything is unclear,
    > please report it. Shed a light.


    Nice article, but I disagree in the point that @@vars are simpler than
    class instance variables. Class instance variables have odd semantics in
    the current Ruby which means that they will probably do some detail
    different than you expect.

    I've found that sticking to class instance variables (and thus keeping
    things simple -- why do we need another type of variables again?) helps
    in making code easier to understand.

    Perhaps you should display both sides of this in the article.
     
    Florian Groß, Apr 18, 2005
    #4
  5. On Apr 18, 2005, at 6:33 AM, Florian Groß wrote:
    > Nice article, but I disagree in the point that @@vars are simpler than
    > class instance variables. Class instance variables have odd semantics
    > in the current Ruby which means that they will probably do some detail
    > different than you expect.


    But you have to do:

    class Foo
    @var1 = []
    @var2 = {}
    class << self
    attr_accessor :var1, :var2
    end
    end

    to get reasonable access to those class instance variables inside an
    instance method, and even then you have to do self.class.var1


    Once you 'get it' it's not TERRIBLY difficult, but I would say that the
    above is more than enough justification for calling @@foo simpler.
    Simpler, but also confusing in the inherited-class cases. (So confusing
    that I still don't fully grok what specifically occurs that makes @@foo
    unusable, and when it occurs. I'm still grasping at the fringes of the
    tablecloth.)
     
    Gavin Kistner, Apr 18, 2005
    #5
  6. "Florian Groß" <> schrieb im Newsbeitrag
    news:d4093s$dml$...
    > why the lucky stiff wrote:
    >
    > > <http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html>
    > >
    > > I'm hoping this will help uncover the truth. If anything is unclear,
    > > please report it. Shed a light.

    >
    > Nice article, but I disagree in the point that @@vars are simpler than
    > class instance variables. Class instance variables have odd semantics in
    > the current Ruby which means that they will probably do some detail
    > different than you expect.
    >
    > I've found that sticking to class instance variables (and thus keeping
    > things simple -- why do we need another type of variables again?) helps
    > in making code easier to understand.


    +1

    > Perhaps you should display both sides of this in the article.


    Yeah, I missed that, too. In fact, the article seems to discourage class
    instance variable usage...

    Kind regards

    robert
     
    Robert Klemme, Apr 18, 2005
    #6
  7. Re: Article: Seeing Metaclasses Clearly

    why the lucky stiff wrote:
    > I've written a very nuts+bolts article on metaclasses (aka virtual
    > classes or metaobjects), since they still lurk under a shroud of fear


    > and enigma.
    >
    > <http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html>
    >
    > I'm hoping this will help uncover the truth. If anything is unclear,


    > please report it. Shed a light.


    Noticed a small mistake; At one point, you refer to the at-sign (@) as
    an ampersand. Other than that... the article went way over my head and
    twisted my poor brain into knots. :-( I think I'll need to re-read
    chapter 24 of Pickaxe 2 immediately before reading this article.
     
    Karl von Laudermann, Apr 18, 2005
    #7
  8. Florian Groß wrote:
    > Nice article, but I disagree in the point that @@vars are simpler than
    > class instance variables. Class instance variables have odd semantics in
    > the current Ruby which means that they will probably do some detail
    > different than you expect.


    You're right. I'm oversimplifying this. I need to discuss the
    metaclass/inheritance thing a bit more.

    _why
     
    why the lucky stiff, Apr 18, 2005
    #8
  9. why the lucky stiff

    Curt Hibbs Guest

    David A. Black wrote:
    > Hi --
    >
    > On Mon, 18 Apr 2005, why the lucky stiff wrote:
    >
    >> I've written a very nuts+bolts article on metaclasses (aka virtual
    >> classes or
    >> metaobjects), since they still lurk under a shroud of fear and enigma.
    >>
    >> <http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html>
    >>
    >> I'm hoping this will help uncover the truth. If anything is unclear,
    >> please
    >> report it. Shed a light.

    >
    >
    > For some reason the first 1/8 inch or so on the left are cut off on my
    > browser. I don't know whether it's a CSS thing or a browser thing
    > (Netscape 6). So "methods" comes out as "thods", etc.


    Also, in Firefox 1.0 on Windows XP, when I try to print it, it only
    prints the first page. If I use MS Internet Explorer, it prints just fine.

    Curt
     
    Curt Hibbs, Apr 18, 2005
    #9
  10. David A. Black wrote:
    > The tutorial itself looks good, though the terminology in this area
    > continues to be a problem. My understanding is that the most general
    > term is "singleton class", and that "metaclass" is a special term for
    > singleton class of a Class object. (See Pickaxe, 2nd ed., p. 382.)
    > So, for example, I would rename your Object#metaclass method
    > #singleton_class, since it applies to all objects (as per RCR 231).


    Sure, I'm aware that "virtual class" is the generic term, while Matz has
    also used "singleton class" and "meta-object" to describe these classes
    used in tandem with an RObject.

    I only use the term "metaclass" because it is the term predominantly
    used in the PickAxe II. While Dave does interchangibly use "virtual
    class" and "singleton class", the only term he uses to generically refer
    to the construct is "metaclass".

    And I really need to be able to wrap these up in a single word, whilst
    still jiving with the PickAxe.

    _why
     
    why the lucky stiff, Apr 18, 2005
    #10
  11. Re: Article: Seeing Metaclasses Clearly

    Karl von Laudermann wrote:
    > why the lucky stiff wrote:
    > > I've written a very nuts+bolts article on metaclasses (aka virtual
    > > classes or metaobjects), since they still lurk under a shroud of

    fear
    >
    > > and enigma.
    > >
    > >

    <http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html>
    > >
    > > I'm hoping this will help uncover the truth. If anything is

    unclear,
    >
    > > please report it. Shed a light.

    >
    > Noticed a small mistake; At one point, you refer to the at-sign (@)

    as
    > an ampersand. Other than that... the article went way over my head

    and
    > twisted my poor brain into knots. :-( I think I'll need to re-read
    > chapter 24 of Pickaxe 2 immediately before reading this article.


    Glad I'm not the only one who has to go back to the books! (I did spot
    the "ampersand" thing, though).
     
    Mike Woodhouse, Apr 18, 2005
    #11
  12. why the lucky stiff wrote:
    > I've written a very nuts+bolts article on metaclasses (aka virtual
    > classes or metaobjects), since they still lurk under a shroud of fear
    > and enigma.
    >
    > <http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html>
    >
    > I'm hoping this will help uncover the truth. If anything is unclear,
    > please report it. Shed a light.
    >


    One thing I found confusing was the comment for the class_def method

    ># Just defines a class method
    >def class_def name, &blk
    > class_eval { define_method name, &blk }
    >end



    However it actually defines an instance method

    require "metaid"

    class MyClass
    class_def "class_method" do puts "success" end
    end

    MyClass.class_method
    #=> undefined method "class_method" for MyClass:Class

    MyClass.new.class_method #=> success


    --
    Mark Sparshatt
     
    mark sparshatt, Apr 18, 2005
    #12
  13. why the lucky stiff

    Jeffrey Moss Guest

    _why,

    Nice tutorial, I found I learned something from it. I know there is a
    chapter in the pickaxe that attempts to explain this, but this seems to be
    the best (only?) freely available explanation.

    Being somewhat new to the concept of metaprogramming, I can tell you what is
    particularly confusing is the use of class << self, how this is like the
    root of all singleton behavior, how it differs from class a < b (perhaps
    even display how it works inside the interpreter). I wasn't sure what the
    difference between the < and the << operator was, so I had to go look it up.

    Also the difference between class instance variables and class variables
    could use some extra explaining, it seems you're just saying what to do and
    what not to do, but not why you can't or shouldn't do it, and why a @@ class
    variable is handy.

    Thanks,

    -Jeff

    ----- Original Message -----
    From: "why the lucky stiff" <>
    To: "ruby-talk ML" <>
    Sent: Monday, April 18, 2005 12:50 AM
    Subject: [ANN] Article: Seeing Metaclasses Clearly


    > I've written a very nuts+bolts article on metaclasses (aka virtual classes
    > or metaobjects), since they still lurk under a shroud of fear and enigma.
    >
    > <http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html>
    >
    > I'm hoping this will help uncover the truth. If anything is unclear,
    > please report it. Shed a light.
    >
    > Sharkin',
    >
    > _why
    >
    >
     
    Jeffrey Moss, Apr 18, 2005
    #13
  14. why the lucky stiff

    Jeffrey Moss Guest

    That happens to me when I try and print my bank statements, its probably a
    firefox bug.

    -Jeff

    > Also, in Firefox 1.0 on Windows XP, when I try to print it, it only prints
    > the first page. If I use MS Internet Explorer, it prints just fine.
    >
    > Curt
    >
     
    Jeffrey Moss, Apr 18, 2005
    #14
  15. why the lucky stiff

    Lionel Thiry Guest

    mark sparshatt a écrit :
    > why the lucky stiff wrote:
    >
    >> I've written a very nuts+bolts article on metaclasses (aka virtual
    >> classes or metaobjects), since they still lurk under a shroud of fear
    >> and enigma.
    >>
    >> <http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html>
    >>
    >> I'm hoping this will help uncover the truth. If anything is unclear,
    >> please report it. Shed a light.
    >>

    >
    > One thing I found confusing was the comment for the class_def method
    >
    > ># Just defines a class method
    > >def class_def name, &blk
    > > class_eval { define_method name, &blk }
    > >end

    >
    >
    > However it actually defines an instance method
    >
    > require "metaid"
    >
    > class MyClass
    > class_def "class_method" do puts "success" end
    > end
    >
    > MyClass.class_method
    > #=> undefined method "class_method" for MyClass:Class
    >
    > MyClass.new.class_method #=> success
    >


    The only I've found to make your sample code work is to refactor class_def this way:
    def class_def name, &blk
    meta_eval { define_method name, &blk }
    end

    I personnaly feel it weird I could not realise this whithout the help of the
    metaclass manipulation methods _why has added.

    --
    Lionel Thiry
     
    Lionel Thiry, Apr 18, 2005
    #15
  16. why the lucky stiff

    Lionel Thiry Guest

    why the lucky stiff a écrit :
    > I've written a very nuts+bolts article on metaclasses (aka virtual
    > classes or metaobjects), since they still lurk under a shroud of fear
    > and enigma.
    >
    > <http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html>
    >
    > I'm hoping this will help uncover the truth. If anything is unclear,
    > please report it. Shed a light.
    >
    > Sharkin',
    >
    > _why
    >
    >
    >


    Errata

    In the begining of the page:
    "I’ve been keeping these methods in a file called metaid.rb and it’s a start
    toward building a little library that can simplify use of metaclasses. Let’s
    talk about metaclasses and I advise you to keep metaid.rb at your side. Let’s
    talk about metaclasses and I advise you to keep metaid.rb at your side."

    "Let’s talk about metaclasses and I advise you to keep metaid.rb at your side."
    is said twice.

    --
    Lionel Thiry

    Personal website: http://users.skynet.be/lthiry/
     
    Lionel Thiry, Apr 18, 2005
    #16
  17. Jeffrey Moss wrote:

    > Being somewhat new to the concept of metaprogramming, I can tell you
    > what is particularly confusing is the use of class << self, how this
    > is like the root of all singleton behavior, how it differs from class
    > a < b (perhaps even display how it works inside the interpreter). I
    > wasn't sure what the difference between the < and the << operator was,
    > so I had to go look it up.


    My article briefly discusses the singleton class notation (the << you
    are referring to). This notation is very simple to understand once
    you've gotten the hang of:

    1. Objects are containers for instance variables.
    2. Classes are containers for methods and instance variables.

    There are more to objects and classes than this, but for the sake of
    this discussion, it's useful to whittle it down to this.

    a = Object.new
    a.instance_variable_set( "@name", "Jeff" )

    I've created a new object above, storage for instance variables. I've
    added an instance variable to the object. In doing so, I called the
    `instance_variable_set' method. This method isn't contained in the `a'
    object. It's contained way up the inheritance tree, in the Object class.

    Again: the instance variables are stored in the object. The methods are
    stored in a class up the inheritance tree.

    class << a
    def name; @name; end
    end

    We're opening a metaclass here. What is a metaclass? It's method
    storage for an object. An object can only store instance variables.
    The `name' method has been added to the metaclass (the personal method
    storage) for the object `a'.

    The most needlessly confusing construct in Ruby is `class << self'.
    You're simply accessing the method storage for whatever object is
    currently `self'.

    class Dragon
    class << self; p self; end
    end

    Prints: #<Class:Dragon>

    Okay, so we're in the metaclass for a class. But what is that?

    It's method storage for class methods. Normal instance methods are
    stored directly in the class. But class methods are stored in the
    metaclass.

    class Dragon
    def self.me; p self; end # This method is stored in the metaclass
    def me; p self; end # This method is stored in the class
    end

    Dragon.me #=> Dragon
    Dragon.new.me #=> #<Dragon:0x80914e0>

    Everyone who uses class methods uses metaclasses.

    class << Dragon
    def roar; "#<CLASS:ROAR>"; end
    end
    Dragon.roar #=> #<CLASS:ROAR>

    d = Dragon.new
    class << d
    def roar; "#<OBJ:ROAR>"; end
    end
    d.roar #=> #<OBJ:ROAR>

    I don't really get into this in the article, since I've opted to use the
    `metaclass' method and `meta_eval' which are alternate forms of the above.

    The < operator is a completely different operator, used strictly for
    setting the superclass of a class.

    But one handy thing about metaclass (which I believe qualifies them for
    the meta- prefix) is that they follow the inheritance tree, simply
    remaining one level removed.

    >> Dragon.metaclass

    => #<Class:Dragon>
    >> Dragon.metaclass.superclass

    => #<Class:Object>
    >> Dragon.superclass.metaclass

    => #<Class:Object>

    See, an object's metaclass' superclass is the same as the object's
    superclass' metaclass.

    > Also the difference between class instance variables and class
    > variables could use some extra explaining, it seems you're just saying
    > what to do and what not to do, but not why you can't or shouldn't do
    > it, and why a @@ class variable is handy.


    I'll address this once I'm sure I completely understand variable.c and
    have played around with class variables in metaclasses a bit more.

    _why
     
    why the lucky stiff, Apr 18, 2005
    #17
  18. Lionel Thiry wrote:

    > The only I've found to make your sample code work is to refactor
    > class_def this way:
    > def class_def name, &blk
    > meta_eval { define_method name, &blk }
    > end


    That's the `meta_def' you've recreated above.

    The `class_def' method is intended to be used to add instance methods
    (like the `initialize' I'm adding in Dwemthy's Array):

    class Dragon; end
    Dragon.class_def :initialize do
    @life = 11; @strength = 12
    end

    >> d = Dragon.new

    => #<Dragon:0xb7d571e8 @strength=12, @life=11>

    The `meta_def' can be used to add class methods, because of reasons
    stated throughout the article and in my response to Jeff.

    _why
     
    why the lucky stiff, Apr 18, 2005
    #18
  19. why the lucky stiff wrote:

    > The `class_def' method is intended to be used to add instance methods
    > (like the `initialize' I'm adding in Dwemthy's Array):
    >
    > class Dragon; end
    > Dragon.class_def :initialize do
    > @life = 11; @strength = 12
    > end


    Oh, that's already done by Module#define_method then. Perhaps you can
    just make that method public?
     
    Florian Groß, Apr 18, 2005
    #19
  20. From the article

    "It's an important lesson: objects do not store methods, only classes can."

    Might be nice to contrast this with prototype based languages like javascript.

    Or ProtoRuby ;-)

    class ProtoObj
    def initialize
    @methods = {}
    end
    def addMethod(name, &method)
    @methods[name.id2name] = method
    end
    def method_missing(method, *args)
    @methods[method.id2name].call(*args)
    end
    end

    dog = ProtoObj.new
    dog.addMethod:)bark) {
    puts "Bark"
    }
    dog.bark
     
    Lyndon Samson, Apr 18, 2005
    #20
    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. =?Utf-8?B?S3Jpc3RpYW4=?=
    Replies:
    1
    Views:
    315
    Karl Seguin
    Feb 7, 2005
  2. Philip Meyer
    Replies:
    0
    Views:
    451
    Philip Meyer
    Nov 30, 2003
  3. QuantumG
    Replies:
    96
    Views:
    1,591
    Rob Thorpe
    Oct 26, 2004
  4. srikanth
    Replies:
    5
    Views:
    295
    Richard Heathfield
    Feb 28, 2006
  5. Mark Odell

    Using size_t clearly (appropriately?)

    Mark Odell, Jun 28, 2006, in forum: C Programming
    Replies:
    40
    Views:
    1,136
    Stephen Sprunk
    Jul 13, 2006
Loading...

Share This Page