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.

···

--
Posted via http://www.ruby-forum.com/.

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

···

On 05.12.2010 00:27, Matt Slay wrote:

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.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

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.

···

--
Posted via http://www.ruby-forum.com/\.

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 `<main>'

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 07.12.2010 05:56, Matt Slay wrote:

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.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

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.

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

···

On Tue, Dec 7, 2010 at 5:56 AM, Matt Slay <mattslay@jordanmachine.com> wrote:

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.

···

--
Posted via http://www.ruby-forum.com/\.