Better way to read property than using eval()?

Is there a better way to read a property from a model if you have a
string that contains the property name that you want to read?

Here is what I am doing now:

eval(’@tolerance2.’ + @size[2])

I create the @tolerance2 object by using a .find() in Rails, and I have
the string value which the name of the property I need off of the model.

I’m thinking there is a better Ruby way to do this.

Thanks.

On 05.12.2010 00:27, Matt S. wrote:

I’m thinking there is a better Ruby way to do this.
How about:

x = @tolerance2.send(@size[2])

At least this is safer than using eval. Just think what would happen if

@size[2] = ‘to_s and system(“rm -rf /”)’

:slight_smile:

Kind regards

robert

x = @tolerance2.send(@size[2])

Thanks, Robert, this does work fine…

However, in further studies on this topic, I have stumbled across the
.attributes() method, which seems like a more sensibly named thing to
see in code, and appears to accomplish the same thing.

x = @tolerance2.attributes[@size[2]]

Any reason that one is better than the other in my case. I can see that
send() can even call a method, and that could be useful, but in this
case, I am specifically looking for an attribute value by it’s name.

The method you are mentioning must be part of some extension or other
version of Ruby (I used 1.9.1). If you use that anyway you can as well
use that method. If not, you need to decide if you want to add that
dependency to your code.

Kind regards

robert

I think I know what it is: send() is a Ruby method, and the
attributes[] must come from the Rails framework.

Remember in my original post where I said “I create the @tolerance2
object by using a .find() in Rails”.

I know I posted this in a Ruby forum, and I asked for a “a better Ruby
way to do this.”, and you fave tme the Ruby way, and then later I
discovered a Rails way.

On 07.12.2010 05:56, Matt S. wrote:

Any reason that one is better than the other in my case. I can see that
send() can even call a method, and that could be useful, but in this
case, I am specifically looking for an attribute value by it’s name.

irb(main):009:0> class Foo
irb(main):010:1> attr_accessor :bar
irb(main):011:1> end
=> nil
irb(main):012:0> f=Foo.new
=> #Foo:0x10586f08
irb(main):013:0> f.attributes
NoMethodError: undefined method attributes' for #<Foo:0x10586f08> from (irb):13 from /usr/local/bin/irb19:12:in

The method you are mentioning must be part of some extension or other
version of Ruby (I used 1.9.1). If you use that anyway you can as well
use that method. If not, you need to decide if you want to add that
dependency to your code.

Kind regards

robert

On Tue, Dec 7, 2010 at 5:56 AM, Matt S. [email protected]
wrote:

Any reason that one is better than the other in my case. I can see that
send() can even call a method, and that could be useful, but in this
case, I am specifically looking for an attribute value by it’s name.

I would prefer

x = @tolerance2.send(@size[2])

because that will only calculate that one value. Whereas

x = @tolerance2.attributes[@size[2]]

will first prepare an entire hash with all “attributes” and then you
will
only use 1 of those results and leave the rest unused, Which seems
wasting of CPU cycles to me. E.g. try

puts @tolerance2.attributes.inspect

to see what that means. In other cases though, the ‘attributes’ function
can
be very useful, e.g. if you want to process the entire set of
attributes together
as a hash.

HTH,

Peter