Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Why metaclasses?

Reply
Thread Tools

Why metaclasses?

 
 
James Coglan
Guest
Posts: n/a
 
      06-19-2008
[Note: parts of this message were removed to make it a legal post.]

Hello all,

I've dug around a little bit here but can't quite find the answer I'm
looking for. A little background, then I'll get to my question. I write
JS.Class, which is a JavaScript library for doing OOP using Ruby idioms. The
latest stable release bootstraps JavaScript prototypes to build classes with
classical inheritance, mixins etc. It's got many commonly used Ruby
features, including late-bound arguments-optional super(), hooks, include()
and extend(), etc. You can see it here:

http://svn.jcoglan.com/jsclass/tags/...ource/class.js

There are some bugs in this that I'm trying to fix by doing a complete
rewrite. Most notably, super() can only call superclasses, not mixins. In
1.6, Module is a tiny syntactic hack around protecting a set of methods
using closures. In the new version, Module is right at the core and
everything else is implemented using it, so hopefully I'll end up with a
more Ruby-like system. Classes use modules to store their instance methods,
all objects have modules to manage singleton methods etc. The source is
here:

http://svn.jcoglan.com/jsclass/branc...ource/class.js

I've come to this version by poking around in irb and trying to figure out
how Ruby works. So in this rewrite, Module is a class, Class is a class that
inherits from Module. My understanding is that Classes are essentially
Modules that can be instantiated (i.e. they can create new Objects), and
that class inheritance is just a special case of module inclusion. In
JS.Classs I've got metaclasses, except they're actually modules because
that's all I need: something to resolve method lookups etc. that cannot be
instantiated. Turns out using Modules for all these things gets you a very
long way, and teaches you something about inheritance.

So anyway, this question has been really bugging me: in Ruby, how come
metaclasses are just that: classes? Given that you cannot instantiate them,
is there any reason why they need to be classes instead of just modules? I
want this release to be as close to Ruby as possible so if I've seriously
misunderstood something I'd rather be put right.


--
James Coglan

 
Reply With Quote
 
 
 
 
Robert Klemme
Guest
Posts: n/a
 
      06-19-2008
2008/6/19 James Coglan <(E-Mail Removed)>:
> So anyway, this question has been really bugging me: in Ruby, how come
> metaclasses are just that: classes? Given that you cannot instantiate them,


13:32:55 OPSC_Gold_bas_dev_R1.2.2$ irb
Ruby version 1.8.6
irb(main):001:0> x = Class.new
=> #<Class:0x7ff9ece4>
irb(main):002:0> o = x.new
=> #<#<Class:0x7ff9ece4>:0x7ff9b56c>
irb(main):003:0> o.class
=> #<Class:0x7ff9ece4>
irb(main):004:0> o.class == x
=> true
irb(main):005:0> x === o
=> true
irb(main):006:0> y = Class.new x
=> #<Class:0x7ff81dc4>
irb(main):007:0> y.superclass
=> #<Class:0x7ff9ece4>
irb(main):008:0> y.superclass == x
=> true
irb(main):009:0> u = y.new
=> #<#<Class:0x7ff81dc4>:0x7ff77518>
irb(main):010:0> x === u
=> true
irb(main):011:0> y === u
=> true

irb(main):012:0> m = Module.new
=> #<Module:0x7ff6e058>
irb(main):013:0> y.class_eval { include m }
=> #<Class:0x7ff81dc4>
irb(main):014:0> m === u
=> true
irb(main):015:0> y.ancestors
=> [#<Class:0x7ff81dc4>, #<Module:0x7ff6e058>, #<Class:0x7ff9ece4>,
Object, Kernel]
irb(main):016:0>

> is there any reason why they need to be classes instead of just modules? I
> want this release to be as close to Ruby as possible so if I've seriously
> misunderstood something I'd rather be put right.


See above.

Kind regards

robert

--
use.inject do |as, often| as.you_can - without end

 
Reply With Quote
 
 
 
 
James Coglan
Guest
Posts: n/a
 
      06-19-2008
[Note: parts of this message were removed to make it a legal post.]

> 13:32:55 OPSC_Gold_bas_dev_R1.2.2$ irb
> Ruby version 1.8.6
> irb(main):001:0> x = Class.new
> => #<Class:0x7ff9ece4>
> irb(main):002:0> o = x.new
> => #<#<Class:0x7ff9ece4>:0x7ff9b56c>
> irb(main):003:0> o.class
> => #<Class:0x7ff9ece4>
> irb(main):004:0> o.class == x
> => true
> irb(main):005:0> x === o
> => true
> irb(main):006:0> y = Class.new x
> => #<Class:0x7ff81dc4>
> irb(main):007:0> y.superclass
> => #<Class:0x7ff9ece4>
> irb(main):008:0> y.superclass == x
> => true
> irb(main):009:0> u = y.new
> => #<#<Class:0x7ff81dc4>:0x7ff77518>
> irb(main):010:0> x === u
> => true
> irb(main):011:0> y === u
> => true
>
> irb(main):012:0> m = Module.new
> => #<Module:0x7ff6e058>
> irb(main):013:0> y.class_eval { include m }
> => #<Class:0x7ff81dc4>
> irb(main):014:0> m === u
> => true
> irb(main):015:0> y.ancestors
> => [#<Class:0x7ff81dc4>, #<Module:0x7ff6e058>, #<Class:0x7ff9ece4>,
> Object, Kernel]
> irb(main):016:0>
>


So x is a class, y is a class that inherits from x (which is to say, y
'includes' x as its first inclusion). o is an x, u is a y (and is therefore
an x). Fine. y includes m, so now u is an m as well. y's ancestors are
itself, m, x, Object and Kernel. Kernel is the root module, Object is the
root class (and therefore includes Kernel). A module's (and therefore a
class's) ancestors are itself and its included modules (and *their* included
modules, depth first). For a class, this means its included modules, its
superclass, its superclass's included modules, and so on.

So far I can't see how this is inconsistent with using metamodules instead
of metaclasses, and with class inheritance being a special case of module
inclusion. With apologies for my apparent slow-wittedness, what am I
missing?

 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      06-20-2008
On 20.06.2008 00:27, James Coglan wrote:
> So far I can't see how this is inconsistent with using metamodules instead
> of metaclasses, and with class inheritance being a special case of module
> inclusion. With apologies for my apparent slow-wittedness, what am I
> missing?


Your quote: "Given that you cannot instantiate them [...]".

Kind regards

robert

 
Reply With Quote
 
Sebastian Hungerecker
Guest
Posts: n/a
 
      06-20-2008
Robert Klemme wrote:
> Your quote: "Given that you cannot instantiate them [...]".


What's wrong with that? You can't.
>> m = class <<Object.new; self end

=> #<Class:#<Object:0xb7b17ae4>>
>> m.new

TypeError: can't create instance of virtual class
from (irb):167:in `new'
from (irb):167
from :0
>> m.allocate

TypeError: can't create instance of virtual class
from (irb):168:in `allocate'
from (irb):168
from :0


--
Jabber: http://www.velocityreviews.com/forums/(E-Mail Removed)
ICQ: 205544826

 
Reply With Quote
 
Calamitas
Guest
Posts: n/a
 
      06-20-2008
On Thu, Jun 19, 2008 at 3:23 PM, James Coglan <(E-Mail Removed)> wrote:
> So anyway, this question has been really bugging me: in Ruby, how come
> metaclasses are just that: classes? Given that you cannot instantiate them,
> is there any reason why they need to be classes instead of just modules? I
> want this release to be as close to Ruby as possible so if I've seriously
> misunderstood something I'd rather be put right.


Well, I don't think instantiability by itself is a requirement for a
class. Binding is a class, but you can't instantiate it (yourself)
either. Not quite the same, I know. The singleton pattern prohibits
explicit instantiation. Again, slightly different maybe, although very
much the same as in both cases there are somewhat artificial
restrictions built in to enforce a concept.

But do singleton modules make sense? Modules can be included in other
classes, but it makes little sense to include a singleton module in
another class because then it would no longer be a *singleton module*.
So singleton modules would be unincludable modules.

So what's better, uninstantiable classes are unincludable modules?
Somewhat arbitrary choice, but as mentioned above, uninstantiable
classes have precedent.

My 2 cents...

Peter

 
Reply With Quote
 
James Coglan
Guest
Posts: n/a
 
      06-20-2008
[Note: parts of this message were removed to make it a legal post.]

2008/6/20 Calamitas <(E-Mail Removed)>:

> On Thu, Jun 19, 2008 at 3:23 PM, James Coglan <(E-Mail Removed)>
> wrote:
> > So anyway, this question has been really bugging me: in Ruby, how come
> > metaclasses are just that: classes? Given that you cannot instantiate

> them,
> > is there any reason why they need to be classes instead of just modules?

> I
> > want this release to be as close to Ruby as possible so if I've seriously
> > misunderstood something I'd rather be put right.

>
> Well, I don't think instantiability by itself is a requirement for a
> class. Binding is a class, but you can't instantiate it (yourself)
> either. Not quite the same, I know. The singleton pattern prohibits
> explicit instantiation. Again, slightly different maybe, although very
> much the same as in both cases there are somewhat artificial
> restrictions built in to enforce a concept.
>
> But do singleton modules make sense? Modules can be included in other
> classes, but it makes little sense to include a singleton module in
> another class because then it would no longer be a *singleton module*.
> So singleton modules would be unincludable modules.
>
> So what's better, uninstantiable classes are unincludable modules?
> Somewhat arbitrary choice, but as mentioned above, uninstantiable
> classes have precedent.




Singleton classes cannot be 'included' either, which is to say they cannot
be subclassed.

irb(main):006:0> class SillyArray < Array
irb(main):007:1> end
=> nil
irb(main):009:0> s = SillyArray.new [1,2,3,4]
=> [1, 2, 3, 4]
irb(main):011:0> s.class
=> SillyArray
irb(main):012:0> s.class.superclass
=> Array
irb(main):013:0> class MetaArray < [].metaclass
irb(main):014:1> end
TypeError: can't make subclass of virtual class
from (irb):13
from :0

What I'm trying to get at is: given that you can't really do anything
'classy' with a metaclass, it seems they could quite easily be modules
instead, and this makes more sense to me as they are just objects that store
methods. Why do they need to be this specific type of module (i.e. Class)?

 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      06-20-2008
2008/6/20 Sebastian Hungerecker <(E-Mail Removed)>:
> Robert Klemme wrote:
>> Your quote: "Given that you cannot instantiate them [...]".

>
> What's wrong with that? You can't.


Ah, we're running in that terminology issue again: for me Class is a
(or rather "the") metaclass (because it is the class of a class) but
it seems you and probably James as well mean what I am used to call
"singleton class".

So then, yes, those cannot be instantiated.

Cheers

robert

--
use.inject do |as, often| as.you_can - without end

 
Reply With Quote
 
Calamitas
Guest
Posts: n/a
 
      06-20-2008
On Fri, Jun 20, 2008 at 10:48 AM, James Coglan <(E-Mail Removed)> wrote:
> Singleton classes cannot be 'included' either, which is to say they cannot
> be subclassed.
>
> irb(main):006:0> class SillyArray < Array
> irb(main):007:1> end
> => nil
> irb(main):009:0> s = SillyArray.new [1,2,3,4]
> => [1, 2, 3, 4]
> irb(main):011:0> s.class
> => SillyArray
> irb(main):012:0> s.class.superclass
> => Array
> irb(main):013:0> class MetaArray < [].metaclass
> irb(main):014:1> end
> TypeError: can't make subclass of virtual class
> from (irb):13
> from :0
>
> What I'm trying to get at is: given that you can't really do anything
> 'classy' with a metaclass, it seems they could quite easily be modules
> instead, and this makes more sense to me as they are just objects that store
> methods. Why do they need to be this specific type of module (i.e. Class)?


I don't know why exactly --only Matz knows-- but IMO the choice is
somewhat arbitrary because whichever is chosen, class or module, you
have to take away some of its typical behaviors to have it be
singletonsomething. My feeling is that we're better off having
singleton *classes*. Modules can appear multiple times in the class
hierarchy and because of that some of the methods on Module behave in
a much less useful way (IMO) than the corresponding methods on Class,
especially when navigating the class hierarchy using #ancestors for
instance. Note that modules also suffer from the double/dynamic
inclusion problem, so things like Object#extend, or class << a ;
include M ; end would need some extra code to make things work like
they do now.

Just remembered this has been discussed before; take a look here:

http://blade.nagaokaut.ac.jp/cgi-bin...by-talk/267106

Peter

 
Reply With Quote
 
Marc Heiler
Guest
Posts: n/a
 
      06-21-2008
> I don't know why exactly --only Matz knows-- but IMO the choice is
> somewhat arbitrary because whichever is chosen, class or module, you
> have to take away some of its typical behaviors to have it be
> singletonsomething.


At times I wanted a language that does away with the distinction between
class and module and objects, and rather focuses on objects, and
behaviour only, with an elegant syntax like ruby has (but less complex
as a whole)
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
why why why why why Mr. SweatyFinger ASP .Net 4 12-21-2006 01:15 PM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
Cisco 2611 and Cisco 1721 : Why , why , why ????? sam@nospam.org Cisco 10 05-01-2005 08:49 AM
Why, why, why??? =?Utf-8?B?VGltOjouLg==?= ASP .Net 6 01-27-2005 03:35 PM
Why Why Why You HAVE NO IDEA MCSE 31 04-24-2004 06:40 PM



Advertisments