Dynamically referring to a Class

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.

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

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:

[[email protected]~]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

On Apr 14, 2008, at 8:41 AM, Eustáquio ‘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 =
“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
=> nil

a = Array
=> Array

a.say_hihi
=> nil

a = Object
=> 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

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,

On Mon, Apr 14, 2008 at 2:32 PM, Gaudi Mi [email protected] wrote:


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

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 {

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

In other words do not store away something just to get it back again :wink:

HTH
Robert


http://ruby-smalltalk.blogspot.com/


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

On Mon, Apr 14, 2008 at 4:42 PM, Marc H. [email protected]
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 © 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


http://ruby-smalltalk.blogspot.com/


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

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.

On Mon, Apr 14, 2008 at 12:32 PM, Robert D. [email protected]
wrote:

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

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

On Apr 14, 2008, at 11:58 PM, Rick DeNatale wrote:

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.

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 G.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)

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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs