[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

how to create an object of a class you don't know yet

Bradley, Todd

12/3/2004 6:45:00 PM

Hi, I'm just now getting into Ruby's OO-ness, and could use some advice.
I'm trying to create an object, but which specific class needs to be
determined at runtime. I figured out how to do this by creating a
string and executing it using the "eval" command, but I know there must
be an easier way. My first guess was to do something like #{answer}.new
but that didn't work.


Here's my code:


class Foo
def method1
end
end

class Bar
def method2
end
end

# Pretend this was determined at runtime
answer = "Foo"


# There must be a better way of doing this:

myobj = Object.new # Needs to exist in this scope
mystring = "myobj = #{answer}.new"

eval mystring

puts "I just created a #{myobj.class} object."




Any advice is appreciated. Thanks in advance!


Todd.



6 Answers

Eric Hodel

12/3/2004 6:56:00 PM

0

On 03 Dec 2004, at 10:44, Bradley, Todd wrote:

> Hi, I'm just now getting into Ruby's OO-ness, and could use some
> advice.
> I'm trying to create an object, but which specific class needs to be
> determined at runtime. I figured out how to do this by creating a
> string and executing it using the "eval" command, but I know there must
> be an easier way. My first guess was to do something like
> #{answer}.new
> but that didn't work.
>
>
> Here's my code:
>
>
> class Foo
> def method1
> end
> end
>
> class Bar
> def method2
> end
> end
>
> # Pretend this was determined at runtime
> answer = "Foo"
>
>
> # There must be a better way of doing this:
>
> myobj = Object.new # Needs to exist in this scope
> mystring = "myobj = #{answer}.new"
>
> eval mystring
>
> puts "I just created a #{myobj.class} object."

klass = answer.split('::').inject(Object) { |klass,const|
klass.const_get const }

myobj = klass.new

In longer terms:

answer.split('::') # for Foo::Bar::Baz nested classes/modules

answer.split('::').inject(Object) do |klass, const| # namespaces start
from Object
klass.const_get const # #inject passes the value of this expression in
# as the first arg to the block, so use that namespace
# to find the next part of the namespace
end

klass = answer.split [...] # #inject returns the last result, which will
# be a class, provided answer references a class

myobj = klass.new # instantiate an instance of the class

You can also do things like this:

KLASSES = { 'html' => HTMLWriter, 'pdf' => PDFWriter, 'plain-text' =>
TextWriter }

output = ARGV.shift

raise "invalid output type" unless KLASSES.include? output

writer = KLASSES[output].new



Francis Hwang

12/3/2004 6:57:00 PM

0

"new" is just a class method, and you can call class methods on classes
that aren't bound at the time of interpretation. For example:

instance = MyClass.new

is the same as

a_class = MyClass
instance = a_class.new

So you can do things like:

irb(main):001:0> classes = [ String, Hash, Array ]
=> [String, Hash, Array]
irb(main):002:0> grab_bag = classes.collect { |a_class| a_class.new }
=> ["", {}, []]



On Dec 3, 2004, at 1:44 PM, Bradley, Todd wrote:

> Hi, I'm just now getting into Ruby's OO-ness, and could use some
> advice.
> I'm trying to create an object, but which specific class needs to be
> determined at runtime. I figured out how to do this by creating a
> string and executing it using the "eval" command, but I know there must
> be an easier way. My first guess was to do something like
> #{answer}.new
> but that didn't work.
>
>
> Here's my code:
>
>
> class Foo
> def method1
> end
> end
>
> class Bar
> def method2
> end
> end
>
> # Pretend this was determined at runtime
> answer = "Foo"
>
>
> # There must be a better way of doing this:
>
> myobj = Object.new # Needs to exist in this scope
> mystring = "myobj = #{answer}.new"
>
> eval mystring
>
> puts "I just created a #{myobj.class} object."
>
>
>
>
> Any advice is appreciated. Thanks in advance!
>
>
> Todd.
>
>

Francis Hwang
http://f...



Daneel van Tonder

12/4/2004 9:38:00 AM

0

Bradley, Todd wrote:
> Hi, I'm just now getting into Ruby's OO-ness, and could use some advice.
> I'm trying to create an object, but which specific class needs to be
> determined at runtime. I figured out how to do this by creating a
> string and executing it using the "eval" command, but I know there must
> be an easier way. My first guess was to do something like #{answer}.new
> but that didn't work.
>
>
> Here's my code:
>
>
> class Foo
> def method1
> end
> end
>
> class Bar
> def method2
> end
> end
>
> # Pretend this was determined at runtime
> answer = "Foo"
>
>
> # There must be a better way of doing this:
>
> myobj = Object.new # Needs to exist in this scope
> mystring = "myobj = #{answer}.new"
>
> eval mystring
>
> puts "I just created a #{myobj.class} object."
>
>
>
>
> Any advice is appreciated. Thanks in advance!
>
>
> Todd.
>
>
>
class GMClassManager
@@classHash = { 'CLASS_ROOM_DEFAULT' => GMRoom,
'CLASS_ROOM_LOGIN' => GMLoginRoom,
}

def GMClassManager.getRoomObject( valueClassId )
tmpClass = @@classHash[ valueClassId ]
if not tmpClass == nil
tmpClass.new
else
nil
end
end
end


This works for me

Florian Gross

12/4/2004 3:08:00 PM

0

Daneel van Tonder wrote:

> class GMClassManager
> @@classHash = { 'CLASS_ROOM_DEFAULT' => GMRoom,
> 'CLASS_ROOM_LOGIN' => GMLoginRoom,
> }

Using a constant instead would be nicer, I think.

Mitchell Holman

1/21/2012 2:54:00 AM

0

Paul David Wright <pauldavidwright@yahoo.com> wrote in
news:Xns9FE0C0CA2ED91pauldavidwrightyahoo@178.63.61.175:

> Mitchell Holman <nomailcomcast.net> wrote in
> news:Xns9FE0ADE82AD26nomailcomcastnet@216.196.121.131:
>
>
>> John Manning <jrobertm@terra.com.br> wrote in
>> news:rtCdna1dIvRTSYTSnZ2dnUVZ_oWdnZ2d@giganews.com:
>>
>>>
>>>
>>> Chronicling Mitt?s mendacity
>>>
>>> By Washington Monthly's Steve Benen
>>>
>>>
>>> Two weeks ago, I launched a new Friday afternoon feature,
>>> highlighting the most offensive Mitt Romney falsehoods of
>>> the week. Last Friday?s installment was well received, so
>>> let?s keep this going with a third.
>>>
>>>
>>> 1. "The president is planning on cutting $1 trillion out of
>>> military
>>> spending."
>>>
>>> That's a Romney favorite, but it?s not at all accurate.
>>
>>
>> Too bad, the military budget NEEDS to be cut.
>>
>> 700 military bases scattered across 192 countries -
>>
>> Is that really necessary, Republicans?
>>
>>
>>
>>
>
> Ubfortunetly, I'm sure they will say, "Totally necessary!" and "If you
> don't agree, you 'anti-American."
>


When a Republican cuts the defense budget it is
"trimming unnecessary spending", when a Democrat does
the same thing it is "gutting the military"





Syd M.

1/22/2012 1:08:00 AM

0

Mitchell Holman <nomailcomcast.net> wrote in
news:Xns9FE0D375621Bnomailcomcastnet@216.196.121.131:


> Paul David Wright <pauldavidwright@yahoo.com> wrote in
> news:Xns9FE0C0CA2ED91pauldavidwrightyahoo@178.63.61.175:
>
>> Mitchell Holman <nomailcomcast.net> wrote in
>> news:Xns9FE0ADE82AD26nomailcomcastnet@216.196.121.131:
>>
>>
>>> John Manning <jrobertm@terra.com.br> wrote in
>>> news:rtCdna1dIvRTSYTSnZ2dnUVZ_oWdnZ2d@giganews.com:
>>>
>>>>
>>>>
>>>> Chronicling Mitt?s mendacity
>>>>
>>>> By Washington Monthly's Steve Benen
>>>>
>>>>
>>>> Two weeks ago, I launched a new Friday afternoon feature,
>>>> highlighting the most offensive Mitt Romney falsehoods of
>>>> the week. Last Friday?s installment was well received, so
>>>> let?s keep this going with a third.
>>>>
>>>>
>>>> 1. "The president is planning on cutting $1 trillion out of
>>>> military
>>>> spending."
>>>>
>>>> That's a Romney favorite, but it?s not at all accurate.
>>>
>>>
>>> Too bad, the military budget NEEDS to be cut.
>>>
>>> 700 military bases scattered across 192 countries -
>>>
>>> Is that really necessary, Republicans?
>>>
>>>
>>>
>>>
>>
>> Ubfortunetly, I'm sure they will say, "Totally necessary!" and "If
>> you don't agree, you 'anti-American."
>>
>
>
> When a Republican cuts the defense budget it is
> "trimming unnecessary spending", when a Democrat does
> the same thing it is "gutting the military"
>
>
>
>
>
>

Well, Rethuglians are not known for their honesty...

--
PDW

Check out my blog:
The first is a preview of my superhero comic book.
http://incognitoheroes.blo...
http://corneliusaddaptionproject.blo...


And my books:
http://www.lulu.com/spotlight/...