[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Dynamic object creation in ruby

Clash Fasn

3/29/2009 3:30:00 AM

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-....

6 Answers

David Masover

3/29/2009 4:49:00 AM

0

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')

lasitha

3/29/2009 4:54:00 AM

0

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-....

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

Brian Candler

3/29/2009 11:40:00 AM

0


> 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-....

Robert Klemme

3/29/2009 1:54:00 PM

0

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")

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

pjb

3/29/2009 2:39:00 PM

0

Robert Klemme <shortcutter@googlemail.com> writes:

> 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")
>
> 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.


--
__Pascal Bourguignon__

Robert Klemme

3/29/2009 3:55:00 PM

0

On 29.03.2009 16:38, Pascal J. Bourguignon wrote:
> Robert Klemme <shortcutter@googlemail.com> writes:
>
>> 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")
>> 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