Anonymous classes?

Here is what I’d like to do.

anonymous_class = class.new;

somehow define methods on anonymous_class

somehow create an object of type anonymous_class

And I’m running into a roadblock. I can create an anonymous class
easily enough, I just can’t figure out how to define methods on it.
Like initialize. Or create objects of that type.

Yes, I know about singleton classes, but they don’t do what I want
because I also want to create subclasses of these subclasses, and
instances of these subclasses.

As for why I want this, I’m trying to see whether I can figure out how
to implement a decent prototype based class system in Ruby. A friend
says that you can’t. I thought that a clean way to do it would be to
create an anonymous class, and create an object Prototype of that class.
I would make sure that Prototype’s new method would create a new class
which is a subclass of Prototype’s, and an object of that class with the
prototype being the object that new was called on. And Prototype would
have a def method which would define new methods in the class of the
object that def was called on.

And yes, I know I could do this by dynamically creating normal classes
with calls to eval. But I’d prefer to avoid going there.

Thanks,
Ben

On Oct 20, 2007, at 10:28 PM, Ben Tilly wrote:

Like initialize. Or create objects of that type.
I would make sure that Prototype’s new method would create a new class
Thanks,
Ben

Posted via http://www.ruby-forum.com/.

http://codeforpeople.com/lib/ruby/prototype/prototype-2.0.0/README

Cheers-
Ezra Z.
Founder & Ruby Hacker
[email protected]

Ben Tilly wrote:

Here is what I’d like to do.

anonymous_class = class.new;

somehow define methods on anonymous_class

anonymous_class.send(:define_method,:my_method) {|x| puts x}
anonymous_class.class_eval do
def chunky()
“bacon”
end
end

Or just:
anonymous_class = Class.new do
def chunky
“bacon”
end
end

somehow create an object of type anonymous_class

my_object = anonymous_class.new

HTH,
Sebastian

Re: Anonymous classes?
Posted by Ben Tilly (btilly) on 21.10.2007 07:28
Here is what I’d like to do.

anonymous_class = class.new;

somehow define methods on anonymous_class

somehow create an object of type anonymous_class

Here’s yet another take on it: http://snippets.dzone.com/posts/show/3378
and http://ruby-smalltalk.blogspot.com

Cheers

j. k.

Jimmy K. wrote:

Re: Anonymous classes?
Posted by Ben Tilly (btilly) on 21.10.2007 07:28
[…]
Here’s yet another take on it: http://snippets.dzone.com/posts/show/3378
and http://ruby-smalltalk.blogspot.com

Very cute.

Unfortunately doesn’t work in old versions of Ruby. (I tried in 1.6.8.)

Ben

Ben Tilly wrote:

Here is what I’d like to do.

anonymous_class = class.new;

somehow define methods on anonymous_class

somehow create an object of type anonymous_class

How about something like this:

Dog = Class.new {
def self.create_method(name, proc_)
self.send(:define_method, name, proc_)
end
}

p = lambda {puts “Woof, woof.”}
Dog.create_method(:bark, p)

d = Dog.new
d.bark

Ezra Z. wrote:

On Oct 20, 2007, at 10:28 PM, Ben Tilly wrote:

Like initialize. Or create objects of that type.
I would make sure that Prototype’s new method would create a new class
Thanks,
Ben

Posted via http://www.ruby-forum.com/.

http://codeforpeople.com/lib/ruby/prototype/prototype-2.0.0/README

If I’d seen that before I implemented mine, I would have just shown
that. However I already have another one. I did borrow some ideas from
that one. Here goes:

class PrototypeClass
attr_reader :prototype

def initialize (*prototype)
  @prototype = prototype[0]
end

def new (*definitions)
  new_class = Class.new(self.class)
  for definition in definitions
    new_class.module_eval definition
  end
  return new_class.new(self)
end

def def (definition)
  self.class.module_eval "def #{definition} end"
end

def include (mod)
  self.class.module_eval "include #{mod}"
end

end

Prototype = PrototypeClass.new(nil)

And here is a sample of usage:

@foo = Prototype.new %q{
attr_accessor :name
}
@bar = @foo.new
@baz = @bar.new

@foo.name = “foo”
@bar.name = “bar”
@baz.name = “baz”

def test_greet
try_greet = lambda {|obj|
if obj.respond_to? :greet
obj.greet(obj.name)
else
puts obj.name
puts “Object #{obj.name} (#{obj.id}) cannot greet”
end
}
try_greet[@foo]
try_greet[@bar]
try_greet[@baz]
end

test_greet()

@bar.def %q{ greet (name)
puts “Greeting from #{name} (id #{self.id})”
}

puts “Defined bar.greet”

test_greet()

module Mod
def greet (name)
puts “Hello from #{name} (#{self.id})”
end
end

@foo.include(Mod)
puts “Included module”

test_greet()

Cheers,
Ben

7stud – wrote:

Ben Tilly wrote:
How about something like this:

Dog = Class.new {
def self.create_method(name, proc_)
self.send(:define_method, name, proc_)
end
}

p = lambda {puts “Woof, woof.”}
Dog.create_method(:bark, p)

d = Dog.new
d.bark

I tried this, but when I went with my inherited objects, I was not
picking up the IDs of the inherited objects correctly.

Cheers,
Ben