Lets say I have a two classes, Foo and Bar.
In some code, I have a variable that can either contain the test ‘Foo’
or the text ‘Bar’. If it contains Foo, I would like to call Foo.new
(v1, v2), if it contains Bar, I would like to call Bar.new(v1, v2).
Obviously I could create an IF statement, such as
if var == ‘Foo’ then
Foo.new(…)
elsif var == ‘Bar’ then
Bar.new(…)
end if
Or if I want to get fancy, maybe a dispatch table:
dispatch = {
‘Foo’ => Foo,
‘Bar’ => Bar
}
obj = dispatch[var].new(…)
Is there another Ruby way to do this sort of thing?
Thanks,
Stephen.
On Wed, Apr 8, 2009 at 2:40 PM, stephen O’D
[email protected]wrote:
dispatch = {
‘Foo’ => Foo,
‘Bar’ => Bar
}
obj = dispatch[var].new(…)
Is there another Ruby way to do this sort of thing?
Object.const_get(var).new(…)
or with ActiveSupport:
var.constantize.new(…)
On Apr 8, 2009, at 4:40 PM, stephen O’D wrote:
dispatch = {
‘Foo’ => Foo,
‘Bar’ => Bar
}
obj = dispatch[var].new(…)
This can sometimes be the best approach because if you simply
translate arbitrary text to a class name you are allowing arbitrary
classes to be instantiated. It just depends on where your text is
coming from.
Rick DeNatale recently posted in [ruby-talk:332670] this nice solution
to mapping text to class objects:
On Apr 8, 10:01 pm, Tony A. [email protected] wrote:
medioh.com
Thanks, works perfectly!
On Apr 8, 10:13 pm, Gary W. [email protected] wrote:
translate arbitrary text to a class name you are allowing arbitrary
inject(Object) { |scope, name| scope.const_defined?(name) ?
scope.const_get(name) : scope.const_missing(name) }
end
Thanks for the tip - I think my data is well enough sanitized, but
you just never know so I may well use this approach. Knowing how to
do things with Object.const_get is useful even if I don’t use it.