Anonymous classes?

B

Ben Tilly

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
 
E

Ezra Zygmuntowicz

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

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

Cheers-
Ezra Zygmuntowicz
Founder & Ruby Hacker
(e-mail address removed)
EngineYard.com
 
S

Sebastian Hungerecker

Ben said:
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
 
7

7stud --

Ben said:
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
 
B

Ben Tilly

Ezra said:

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
 
B

Ben Tilly

7stud said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top