Anonymous classes?

Discussion in 'Ruby' started by Ben Tilly, Oct 21, 2007.

  1. Ben Tilly

    Ben Tilly Guest

    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
    --
    Posted via http://www.ruby-forum.com/.
    Ben Tilly, Oct 21, 2007
    #1
    1. Advertising

  2. On Oct 20, 2007, at 10:28 PM, 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
    >
    > 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
    > --
    > Posted via http://www.ruby-forum.com/.
    >


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

    Cheers-
    Ezra Zygmuntowicz
    Founder & Ruby Hacker

    EngineYard.com
    Ezra Zygmuntowicz, Oct 21, 2007
    #2
    1. Advertising

  3. 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
    --
    NP: Mysticum - Let the Kingdom Come
    Jabber:
    ICQ: 205544826
    Sebastian Hungerecker, Oct 21, 2007
    #3
  4. Ben Tilly

    7stud -- Guest

    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


    --
    Posted via http://www.ruby-forum.com/.
    7stud --, Oct 21, 2007
    #4
  5. Ben Tilly

    Jimmy Kofler Guest

    Jimmy Kofler, Oct 21, 2007
    #5
  6. Ben Tilly

    Ben Tilly Guest

    Ben Tilly, Oct 21, 2007
    #6
  7. Ben Tilly

    Ben Tilly Guest

    Ezra Zygmuntowicz 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
    --
    Posted via http://www.ruby-forum.com/.
    Ben Tilly, Oct 21, 2007
    #7
  8. Ben Tilly

    Ben Tilly Guest

    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
    --
    Posted via http://www.ruby-forum.com/.
    Ben Tilly, Oct 21, 2007
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. VisionSet
    Replies:
    4
    Views:
    479
    Bent C Dalager
    Dec 5, 2003
  2. Scott Simpson
    Replies:
    8
    Views:
    1,017
    Stefan Ram
    Jan 13, 2006
  3. Reporter
    Replies:
    3
    Views:
    465
    Mike Schilling
    May 12, 2007
  4. Rit
    Replies:
    23
    Views:
    921
    Mike Schilling
    Jan 3, 2010
  5. Replies:
    1
    Views:
    212
Loading...

Share This Page