tags:

views:

51

answers:

2

I'm trying to evaluate something like this but more complex, but I get a TypeError because apparently you can't convert a hash to a string. Without changing my entire script, is there a decent workaround for this already ugly workaround?

hash = { :somestuff => "etc", ... }
eval module + "::" + object + "." + function + "(" + hash + ")"

Just an example of what I'm trying to do.

Thanks!

+2  A: 

Well, stating that module, object and function are strings, I think a better way to do this would be:

module_klass = Kernel.const_get(module)
klass = module_klass.const_get(object)
klass.send(function.to_sym, hash)

Kernel.const_get will give you any constant (in this case a constant with the module instance) and it will put it on the module_klass variable. This will be the same as doing eval(module) but less expensive.

To get classes or modules declared inside this module_klass you need to invoke const_get on this instance, once you got that, you just use the send method, this will call the methods you specify in the first parameter, and will pass to this functions the following parameters that are given.

If for any reason this is not working for you, your solution might work if you just do:

hash = { :somestuff => "etc", ... }
eval(module + "::" + object + "." + function + "(" + hash.inspect + ")")

But IMO that's not as elegant and also is likely to be a slower implementation.

Hope that helps.

Roman Gonzalez
A: 

Roman showed you the correct way to do it. However, if you're in Rails (or somewhere where ActiveSupport is loaded) you can also use:

klass = "#{module}::#{class}".constantize
klass.send function, hash
severin