From: Christoph Date: 2005-05-01T09:34:08+09:00 Subject: Re: instantiating metaclasses, sorta [Was: determining when inside 'class << self'] Jim Freeze schrieb: >* Mark Hubbart [2005-04-30 16:35:16 +0900]: > > > >>While experimenting with this, I discovered something interesting: it >>is possible to instantiate a metaclass. By duping a metaclass, you >>regain the ability to instantiate it, apparently without losing any >>functionality. >> >> > >As is said later, duping the object 'erases' the singleton methods >while 'cloning' carries them over. > >I've always considered duping as a nice way of erasing the 'specialness' >of an object while returning it to its natural state. > > It's true that duping erases class method for general objects - it's FALSE for Module objects! --- module A def self.bla puts "bla" end end A.dup.bla # bla Foo = class << 1.0; def self.bar; puts "bar" end; self end.dup class Bar < Foo puts ancestors.join(" < ") # Bar < Foo < Float < Precision < Numeric < Comparable < Object < Kernel end Bar.bar # bar --- I am not sure if I would read to much into this behavior. Here is another curiosity. If you clone a singleton you end up with a "virtual class" which is not the virtual class of any living Object. I guess the only usefully thing you can do with this class is duping it:-) --- Once = class << one = []; self end Twice = Once.clone begin Class.new(Twice) rescue TypeError=> mes puts mes # can't make subclass of virtual class end class Once def okay end end class Twice def fails end end one.okay begin one.fails rescue NoMethodError=> mes puts mes # undefined method `fails' for []:Array end found = nil ObjectSpace.each_object do |o| found = o if Twice == class << o; self end end p found # nil class Third < Twice.dup end p Third.new(1){3} # [3] --- /Christoph