[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Dynamically referring to a Class

Gaudi Mi

4/14/2008 12:33:00 PM

I have several classes in my application, e.g. Person, Employer, Office.
And obviously I have some Class methods for each, e.g. Person.find.

At one point in my application I will be referencing the Class name
dynamically, I will have it in a String. So e.g. class = "Person". I
want to send the Person class the 'find' message (call Person.find).
How do I do this in Ruby. I've scoured the API and Google but it's a
hard thing to search for.

Thanks.
--
Posted via http://www.ruby-....

9 Answers

Stefano Crocco

4/14/2008 12:38:00 PM

0

On Monday 14 April 2008, Gaudi Mi wrote:
> I have several classes in my application, e.g. Person, Employer, Office.
> And obviously I have some Class methods for each, e.g. Person.find.
>
> At one point in my application I will be referencing the Class name
> dynamically, I will have it in a String. So e.g. class = "Person". I
> want to send the Person class the 'find' message (call Person.find).
> How do I do this in Ruby. I've scoured the API and Google but it's a
> hard thing to search for.
>
> Thanks.

Object.const_get(cls).find

If the class is defined in a module, replace Object with the name of the
module. For example:

module M
class C
def self.find
end
end
end

M.const_get('C').find

I hope this helps

Stefano

Eustaquio 'TaQ' Rangel

4/14/2008 12:41:00 PM

0

> At one point in my application I will be referencing the Class name
> dynamically, I will have it in a String. So e.g. class = "Person". I
> want to send the Person class the 'find' message (call Person.find).

Maybe like:

[taq@~]irb
>> class Person; def self.say_hi; puts "hi"; end; end
=> nil
>> s = "Person"
=> "Person"
>> Object.const_get(s).say_hi
hi
=> nil
>> Object.const_get(s).send(:say_hi)
hi
=> nil

fedzor

4/14/2008 2:09:00 PM

0


On Apr 14, 2008, at 8:41 AM, Eust=E1quio 'TaQ' Rangel wrote:
>> At one point in my application I will be referencing the Class name
>> dynamically, I will have it in a String. So e.g. class =3D =20
>> "Person". I
>> want to send the Person class the 'find' message (call Person.find).

Also, if you want, you can ditch the string.

[ari: ~] irb
>> class Array; def self.say_hi; puts "hi"; end; end
=3D> nil
>> a =3D Array
=3D> Array
>> a.say_hihi
=3D> nil
>> a =3D Object
=3D> Object
>> a.say_hi
NoMethodError: undefined method `say_hi' for Object:Class
from (irb):5
from :0
>> x
[ari: ~]

Classes are objects too, Remeber....
-------------------------------------------------------|
~ Ari
seydar: it's like a crazy love triangle of Kernel commands and C code



Eustaquio 'TaQ' Rangel

4/14/2008 2:17:00 PM

0

fedzor wrote:
> Also, if you want, you can ditch the string.
> Classes are objects too, Remeber....

Yeah, but seems that on his problem he needs a string to find the class, so he
can't point straight to the class.

Regards,

Robert Dober

4/14/2008 2:32:00 PM

0

On Mon, Apr 14, 2008 at 2:32 PM, Gaudi Mi <gaudimila@yahoo.com> wrote:
> I have several classes in my application, e.g. Person, Employer, Office.
> And obviously I have some Class methods for each, e.g. Person.find.
>
> At one point in my application I will be referencing the Class name
> dynamically, I will have it in a String. So e.g. class = "Person". I
> want to send the Person class the 'find' message (call Person.find).
> How do I do this in Ruby. I've scoured the API and Google but it's a
> hard thing to search for.
>
> Thanks.
> --
> Posted via http://www.ruby-....
>
>

Hmm others have told you how to do what you wanted. I however wonder
if the need of doing metaprogramming to
find your classes is really a good sign for your design.

If the following is feasible for you I might suggest something like
the following

MyClasses = { "Person" => Person, "Animal" => Animal ... }

or even

MyClasses={}
MyClasses["Person"] = Class::new {
<your code here />
}
MyClasses["Animal"] = Class::new {
<still your code here ;)/>
}

In other words do not store away something just to get it back again ;)

HTH
Robert

--
http://ruby-smalltalk.blo...

---
Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

Marc Heiler

4/14/2008 2:42:00 PM

0

> I however wonder if the need of doing metaprogramming to
> find your classes is really a good sign for your design.

I am not to judge about his design, but I believe using .send and
Object.const_get is not really "metaprogramming". They seem
to be perfectly valid Ruby idioms.

I'd say metaprogramming starts much later when one uses or relies on any
of the *eval* methods. But maybe others will think that method_missing
is a sign of metaprogramming ... maybe the word metaprogramming is
just another way to state that something is quite complex.
--
Posted via http://www.ruby-....

Robert Dober

4/14/2008 4:32:00 PM

0

On Mon, Apr 14, 2008 at 4:42 PM, Marc Heiler <shevegen@linuxmail.org> wrote:
> > I however wonder if the need of doing metaprogramming to
> > find your classes is really a good sign for your design.
>
> I am not to judge about his design, but I believe using .send and
> Object.const_get is not really "metaprogramming". They seem
> to be perfectly valid Ruby idioms.

Oh I did not want to judge, I am always having strong opinions loosely
hold (C) Rick de Natale ;).
I am also open to discussion where metaprogramming begins.
The point I am maintaining though is simply

Consider redesigning in case you have to use that kind of machinery.
If after consideration you think it still is a good design keep it of
course.

Very often a redesign will be too costly or even impossible anyway,
but in some cases this might be an alarm bell.

Just my 0.02$ and sorry for having been too bold ;).

Cheers
Robert
>
> I'd say metaprogramming starts much later when one uses or relies on any
> of the *eval* methods. But maybe others will think that method_missing
> is a sign of metaprogramming ... maybe the word metaprogramming is
> just another way to state that something is quite complex.
> --
>
>
> Posted via http://www.ruby-....
>
>



--
http://ruby-smalltalk.blo...

---
Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

Rick DeNatale

4/14/2008 9:58:00 PM

0

On Mon, Apr 14, 2008 at 12:32 PM, Robert Dober <robert.dober@gmail.com> wrote:
> On Mon, Apr 14, 2008 at 4:42 PM, Marc Heiler <shevegen@linuxmail.org> wrote:
> > > I however wonder if the need of doing metaprogramming to
> > > find your classes is really a good sign for your design.
> >
> > I am not to judge about his design, but I believe using .send and
> > Object.const_get is not really "metaprogramming". They seem
> > to be perfectly valid Ruby idioms.
>
> Oh I did not want to judge, I am always having strong opinions loosely
> hold (C) Rick de Natale ;).
> I am also open to discussion where metaprogramming begins.

Whether or not send and const_get are metaprogramming aside, I think
the real issue here is security.

Using strings which come from a user and arbitrarily getting a class
or sending a message can open Pandora's box.

Not that it's to be avoided completely, just that it raises a flag to
think about the security aspects.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Florian Gilcher

4/14/2008 10:26:00 PM

0

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


On Apr 14, 2008, at 11:58 PM, Rick DeNatale wrote:
> On Mon, Apr 14, 2008 at 12:32 PM, Robert Dober
> <robert.dober@gmail.com> wrote:
>> On Mon, Apr 14, 2008 at 4:42 PM, Marc Heiler
>> <shevegen@linuxmail.org> wrote:
>>>> I however wonder if the need of doing metaprogramming to
>>>> find your classes is really a good sign for your design.
>>>
>>> I am not to judge about his design, but I believe using .send and
>>> Object.const_get is not really "metaprogramming". They seem
>>> to be perfectly valid Ruby idioms.
>>
>> Oh I did not want to judge, I am always having strong opinions
>> loosely
>> hold (C) Rick de Natale ;).
>> I am also open to discussion where metaprogramming begins.
>
> Whether or not send and const_get are metaprogramming aside, I think
> the real issue here is security.
>
> Using strings which come from a user and arbitrarily getting a class
> or sending a message can open Pandora's box.
>
> Not that it's to be avoided completely, just that it raises a flag to
> think about the security aspects.
>
> --
> Rick DeNatale
>
> My blog on Ruby
> http://talklikeaduck.denh...
>

Actually, in Ruby 1.8, this is a real issue. In Ruby 1.8, #const_get
finds every valid constant within the context of your Module, even
inherited ones.

>> class A
>> end
=> nil
>> module C
>> class B
>> end
>> end
=> nil
>> C.const_get("A")
=> A
>>

In Ruby 1.9, there is the possibility avoiding this:

>> class A
>> end
=> nil
>> module C
>> class B
>> end
>> end
=> nil
>> C.const_get("A", false) #don't search for inherited classes
=> A
>>

This gives you the possibility to group allowed Constants in a Module.

Regards,
Florian Gilcher
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)

iEYEARECAAYFAkgD2eQACgkQJA/zY0IIRZYAmQCfQZVPuWM+nUeekiKhtA3ch+5o
qMUAoJZfnL859DD78OfjgobsKm1F/13o
=aVwX
-----END PGP SIGNATURE-----