From: Rajinder Yadav on 15 Dec 2009 03:32 I am just starting to expand my Ruby knowledge into the area of meta-programming. I want to be able to create a class dynamically. Lets call it, class Person, and then I want to add methods to it dynamically. From a static point I have managed to compile the following example: class Person def self.extend_me class_eval "def greet; puts 'hello'; end" instance_eval "def name; puts 'Person'; end" end end Person.extend_me Person.respond_to? :greet Person.respond_to? :name puts Person.name p = Person.new puts p.greet How would I declared a, 'class Person' dynamically and then add methods and attributes to it? Can someone point me to good documentation on this or show me some simple code example? -- Kind Regards, Rajinder Yadav http://DevMentor.org Do Good! - Share Freely
From: Brian Candler on 15 Dec 2009 05:07 Rajinder Yadav wrote: > How would I declared a, 'class Person' dynamically Option 1: since you're using string eval already, you could just do the same. eval "class Person; end" Option 2: Person = Class.new # superclass is Object Person = Class.new(Mammal) # superclass is Mammal I find this isn't often done in practice though. A program which doesn't know in advance which classes it has can be a bit too dynamic :-) You would probably register your classes somewhere to be able to find them. In a Hash is one option; under a Module is another, so you can use MyModule.constants to find them all. You can make your classes anonymous if you don't bind them to a constant: my_klass = Class.new > and then add methods and attributes to it? As you've done before, using string eval, is one way. Another way: Person.class_eval { define_method(:greet) { puts "Hello" } } This means that the method is a closure, and can access variables outside (unlike 'def' which starts a fresh scope), and this can be useful sometimes. Another way: put the method(s) of interest in module(s), then include the relevant ones. Person.class_eval { include Greeter } ActiveRecord is a plentiful source of examples. -- Posted via http://www.ruby-forum.com/.
From: Jesús Gabriel y Galán on 15 Dec 2009 05:49 On Tue, Dec 15, 2009 at 9:32 AM, Rajinder Yadav <devguy.ca(a)gmail.com> wrote: > I am just starting to expand my Ruby knowledge into the area of > meta-programming. > > I want to be able to create a class dynamically. Lets call it, class Person, > and then I want to add methods to it dynamically. > > From a static point I have managed to compile the following example: > > class Person > def self.extend_me > class_eval "def greet; puts 'hello'; end" > instance_eval "def name; puts 'Person'; end" > end > end > > Person.extend_me > > Person.respond_to? :greet > Person.respond_to? :name > > puts Person.name > p = Person.new > puts p.greet > > > How would I declared a, 'class Person' dynamically and then add methods and > attributes to it? Can someone point me to good documentation on this or show > me some simple code example? If you want to define the class dynamically, take a look at Class.new. This creates an anonymous class that you can assign to a constant directly or with const_set. To define methods I would use define_method. Adding attributes is done adding methods that set and get the attributes: irb(main):042:0> C = Class.new do irb(main):043:1* def self.add_method(name, &blk) irb(main):044:2> define_method(name, &blk) irb(main):045:2> end irb(main):046:1> end => C irb(main):051:0> C.add_method(:name) {@name} => #<Proc:0xb7cb9de8@(irb):51> irb(main):052:0> C.add_method(:name=) {|value| @name = value} => #<Proc:0xb7cb3bf0@(irb):52> irb(main):053:0> c = C.new => #<C:0xb7cb16d4> irb(main):054:0> c.name=3 => 3 irb(main):055:0> c.name => 3 Hope this helps, Jesus.
From: Rajinder Yadav on 15 Dec 2009 06:12 Jes�s Gabriel y Gal�n wrote: > On Tue, Dec 15, 2009 at 9:32 AM, Rajinder Yadav <devguy.ca(a)gmail.com> wrote: >> I am just starting to expand my Ruby knowledge into the area of >> meta-programming. >> >> I want to be able to create a class dynamically. Lets call it, class Person, >> and then I want to add methods to it dynamically. >> >> From a static point I have managed to compile the following example: >> >> class Person >> def self.extend_me >> class_eval "def greet; puts 'hello'; end" >> instance_eval "def name; puts 'Person'; end" >> end >> end >> >> Person.extend_me >> >> Person.respond_to? :greet >> Person.respond_to? :name >> >> puts Person.name >> p = Person.new >> puts p.greet >> >> >> How would I declared a, 'class Person' dynamically and then add methods and >> attributes to it? Can someone point me to good documentation on this or show >> me some simple code example? > > If you want to define the class dynamically, take a look at Class.new. > This creates an anonymous class that you can assign to a constant > directly or with const_set. > To define methods I would use define_method. Adding attributes is done > adding methods that set and get the attributes: > > irb(main):042:0> C = Class.new do > irb(main):043:1* def self.add_method(name, &blk) > irb(main):044:2> define_method(name, &blk) > irb(main):045:2> end > irb(main):046:1> end > => C > > irb(main):051:0> C.add_method(:name) {@name} > => #<Proc:0xb7cb9de8@(irb):51> > irb(main):052:0> C.add_method(:name=) {|value| @name = value} > => #<Proc:0xb7cb3bf0@(irb):52> > irb(main):053:0> c = C.new > => #<C:0xb7cb16d4> > irb(main):054:0> c.name=3 > => 3 > irb(main):055:0> c.name > => 3 > > Hope this helps, > > Jesus. > > Hi Jesus, yes it does help and you answered the next question I was about to ask about adding variables after reading Brian's reply. -- Kind Regards, Rajinder Yadav http://DevMentor.org Do Good! - Share Freely
From: Rajinder Yadav on 15 Dec 2009 06:17
Brian Candler wrote: > Rajinder Yadav wrote: >> How would I declared a, 'class Person' dynamically > > Option 1: since you're using string eval already, you could just do the > same. > > eval "class Person; end" > > Option 2: > > Person = Class.new # superclass is Object > Person = Class.new(Mammal) # superclass is Mammal > > I find this isn't often done in practice though. A program which doesn't > know in advance which classes it has can be a bit too dynamic :-) You > would probably register your classes somewhere to be able to find them. > In a Hash is one option; under a Module is another, so you can use > > MyModule.constants > > to find them all. > > You can make your classes anonymous if you don't bind them to a > constant: > > my_klass = Class.new > >> and then add methods and attributes to it? > > As you've done before, using string eval, is one way. > > Another way: > > Person.class_eval { define_method(:greet) { puts "Hello" } } > > This means that the method is a closure, and can access variables > outside (unlike 'def' which starts a fresh scope), and this can be > useful sometimes. > > Another way: put the method(s) of interest in module(s), then include > the relevant ones. > > Person.class_eval { include Greeter } > > ActiveRecord is a plentiful source of examples. Hi Brian, thanks for the excellent examples and explanation =), I can't stop smiling about how beautiful and elegantly simple Ruby make things. -- Kind Regards, Rajinder Yadav http://DevMentor.org Do Good! - Share Freely |