Dynamic object creation in ruby

I'm trying to do dynamic object creation in ruby.

This works:

john = eval("Master::Person").new("John")

This fails:

frank = Object.const_get("Master::Person").new("Frank")

Does anyone know why the second way fails?

···

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

Clash Fasn wrote:

This works:

john = eval("Master::Person").new("John")

This fails:

frank = Object.const_get("Master::Person").new("Frank")

Does anyone know why the second way fails?
  
Because there is no constant named Master::Person. There's a constant named Person inside the constant named Master. This is going to make a lot more sense by example:

Object.const_get('Master').const_get('Person').new('Frank')

For what it's worth, unless there's a reason to use strings, you may as well use symbols there:

Object.const_get(:Master).const_get(:Person).new('Frank')

This will work:
Object.const_get("Master")::Person.new("Frank")

Or:
Object.const_get("Master").const_get("Person").new("Frank")

Or:
"Master::Person".split('::').reduce(Object){|cls, c| cls.const_get(c) }

But your question was 'why?'... I guess the short answer is #const_get
just doesn't interpret the scope operator, '::'. Actually, thinking
of it as an operator (hence it works in eval) and not a naming
convention is perhaps helpful.

cheers,
lasitha

···

On Sun, Mar 29, 2009 at 9:00 AM, Clash Fasn <bangclash@yahoo.com> wrote:

I'm trying to do dynamic object creation in ruby.

This works:

john = eval("Master::Person").new("John")

This fails:

frank = Object.const_get("Master::Person").new("Frank")

Does anyone know why the second way fails?
--
Posted via http://www.ruby-forum.com/\.

frank = Object.const_get("Master::Person").new("Frank")

Does anyone know why the second way fails?

frank = Master.const_get("Person").new("Frank")

···

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

Erm, that's a hybrid solution. If you know the names beforehand, you can just do

frank = Master::Person.new "Frank"

I would assume that the OP receives the full qualified name as a String and wants to get the class from there which can only be achieved with any of the other solutions shown.

Cheers

  robert

···

On 29.03.2009 13:40, Brian Candler wrote:

frank = Object.const_get("Master::Person").new("Frank")

Does anyone know why the second way fails?

frank = Master.const_get("Person").new("Frank")

Robert Klemme <shortcutter@googlemail.com> writes:

frank = Object.const_get("Master::Person").new("Frank")

Does anyone know why the second way fails?

frank = Master.const_get("Person").new("Frank")

Erm, that's a hybrid solution. If you know the names beforehand, you
can just do

frank = Master::Person.new "Frank"

Then the answer for the OP would be:

frank = Object.const_get("Master").const_get("Person").new("Frank")

const_get takes only a simple constant name, not a qualified name.

irb(main):247:0> (module Master
                     (class Person
                         (def initialize(name)
                             @name=name
                             end)
                         end)
                     end)
nil
irb(main):254:0> frank = Object.const_get("Master").const_get("Person").new("Frank")
#<Master::Person:0x3465ac @name="Frank">

I would assume that the OP receives the full qualified name as a
String and wants to get the class from there which can only be
achieved with any of the other solutions shown.

Obviously, he wants to replace the literals by variables.

···

On 29.03.2009 13:40, Brian Candler wrote:

--
__Pascal Bourguignon__

Robert Klemme <shortcutter@googlemail.com> writes:

frank = Object.const_get("Master::Person").new("Frank")

Does anyone know why the second way fails?

frank = Master.const_get("Person").new("Frank")

Erm, that's a hybrid solution. If you know the names beforehand, you
can just do

frank = Master::Person.new "Frank"

Then the answer for the OP would be:

frank = Object.const_get("Master").const_get("Person").new("Frank")

Why would anyone want to use Strings when he knows the names (and consequently their number) beforehand? That does not make sense.

const_get takes only a simple constant name, not a qualified name.

Yes, and that's why the solutions that were provided use some form of String#split to cut a fully qualified name down to individual constants.

I would assume that the OP receives the full qualified name as a
String and wants to get the class from there which can only be
achieved with any of the other solutions shown.

Obviously, he wants to replace the literals by variables.

Apart from the plurals:

This works:

john = eval("Master::Person").new("John")

This fails:

frank = Object.const_get("Master::Person").new("Frank")

Regards

  robert

···

On 29.03.2009 16:38, Pascal J. Bourguignon wrote:

On 29.03.2009 13:40, Brian Candler wrote: