Dynamically referring to a Class

G

Gaudi Mi

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

Stefano Crocco

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
 
E

Eustáquio 'TaQ' Rangel

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@~]irbhi
=> nilhi
=> nil
 
F

fedzor

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

[ari: ~] irbNoMethodError: undefined method `say_hi' for Object:Class
from (irb):5
from :0[ari: ~]

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

Eustáquio 'TaQ' Rangel

fedzor said:
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,
 
R

Robert Dober

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.

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
 
M

Marc Heiler

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

Robert Dober

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
 
R

Rick DeNatale

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

Florian Gilcher

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


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.denhaven2.com/

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.

In Ruby 1.9, there is the possibility avoiding this:

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

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,290
Messages
2,571,454
Members
48,131
Latest member
AntoniaSep

Latest Threads

Top