Ruby's object model has been becoming more strict as of late, preventing some imaginative
(albeit ultimately useless?) tricks like the following prototypish OOP:
a = Object.new
def a.foo; "a#foo" end
a.foo
ProtoA = Class.new(class << a; self.dup end)
b = ProtoA.new
b.foo
RUBY_VERSION
Nowadays, that snippet would die on the Class#dup of the singleton class:
a = Object.new
def a.foo; "a#foo" end
a.foo
ProtoA = Class.new(class << a; self.dup end)
b = ProtoA.new
b.foo
This doesn't mean we cannot do it, though, but it requires some black magic:
a = "foo"
def a.bar; "A#bar" end
proto = a.prototype
proto
proto.superclass
orig = String.instance_methods
proto.instance_methods(true) - orig
ueber_string = proto.new
ueber_string
ueber_string.bar
proto.class_eval do
def initialize(x); super(x.to_s.upcase) end
end
proto.new("hello, world")
object = Object.new
class << object
def foo; "object#foo" end
end
obj = object.prototype.new
obj.foo
def object.bar; "object#bar" end
obj.bar
That's more powerful than a mere Class.new(singleton_class.dup) because
changes in the singleton class affect descendents, as happens with normal
inheritance (for both classes and modules).
Making it happen
Read more...
Read: Tricking that old, picky interpreter: prototype-based OOP