From: Brian Candler Date: 2009-08-25T22:07:47+09:00 Subject: Re: Ruby eval Brandon Larocque wrote: > ( $jobarea == "hi" or $jobarea == "es" ) ? (loop = 9) : ( ($jobarea == > "ca") ? (loop = 8) : (loop = 7) ) > expcost = [] ; exppay = [] ; pay = [] ; name = [] > for i in (1..loop) do > eval("expcost.push $#{$jobarea}_job#{i}.expcost") > eval("exppay.push $#{$jobarea}_job#{i}.exppay") > eval("pay.push $#{$jobarea}_job#{i}.pay") > eval("name.push $#{$jobarea}_job#{i}.name") > end > > Is there any way that I might be able to do this without eval? Or is it > alright the way I have done it? There are two big problems with string eval: it's very slow (especially if used in a loop, as you have done), as it recompiles the string every time it runs; and it may leave your program open to security exploits if any of the data you're eval'ing comes from an external source. So here are some alternatives. Look at 'send' for dynamic method dispatch: x = "hello" m = "upcase" # or m = :upcase x.send(m) Look at 'const_get' for dynamic class/constant access: klass = "String" obj = Object.const_get(klass).new Look at 'instance_variable_set' / 'instance_variable_get' for dynamic access to instance variables: var = :@foo instance_variable_set(var, 123) instance_variable_get(var) I didn't find an equivalent to these methods for global variable access, but that's a pretty horrible way to work anyway. Others have shown that a Hash is the right data structure to use in your code. Look at instance_eval if you just want to run fixed code on a dynamic receiver. s = "hello" s.instance_eval { upcase } -- Posted via http://www.ruby-forum.com/.