Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > eval going boom

Reply
Thread Tools

eval going boom

 
 
Giles Bowkett
Guest
Posts: n/a
 
      06-21-2007
Object X is going to be an exact clone of Object Y, but it's a member
of a different class.

This does not work:

x.attributes.each {|attr, value| eval("y.#{attr}= #{value}")}

irb says:

(eval):1: warning: parenthesize argument(s) for future version
SyntaxError: (eval):1:in `irb_binding': compile error
(eval):1: parse error, unexpected tINTEGER, expecting $
wv.updated_at= Mon May 07 11:13:27 -0700 2007

The second two lines make perfect sense to me; the first two seem pretty weird.

I suppose I should just create an AbstractZ class, from which both Y
and X inherit.

--
Giles Bowkett

Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org

 
Reply With Quote
 
 
 
 
Giles Bowkett
Guest
Posts: n/a
 
      06-21-2007
The problem, basically, is that the attributes come back from
#inspect. So a Date becomes a String (in the example of the error
reported in my previous mail).

This works perfectly:

x.attributes.each {|attr, value| eval("y.#{attr}= x.#{attr}")}

w00t w00t
00ntz 00ntz 00ntz

--
Giles Bowkett

Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org

 
Reply With Quote
 
 
 
 
Bertram Scharpf
Guest
Posts: n/a
 
      06-21-2007
Hi,

Am Donnerstag, 21. Jun 2007, 09:19:47 +0900 schrieb Giles Bowkett:
> This does not work:
>
> x.attributes.each {|attr, value| eval("y.#{attr}= #{value}")}


Maybe #{value.inspect} is better or even

y.send "{#attr}=", value

Untested.

Bertram


--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de

 
Reply With Quote
 
Ryan Davis
Guest
Posts: n/a
 
      06-22-2007

On Jun 20, 2007, at 17:19 , Giles Bowkett wrote:

> Object X is going to be an exact clone of Object Y, but it's a member
> of a different class.
>
> This does not work:
>
> x.attributes.each {|attr, value| eval("y.#{attr}= #{value}")}


>> p x.class

=> CommandsIShouldNeverEval
>> p x.attributes

=> { :z => "`rm -rf /`" }
>> x.attributes.each {|attr, value| eval("y.#{attr}= #{value}")}

...

Don't use eval. There is no need in this example.

CHALLENGE: rewrite the above code to not use eval at all. For that
matter, don't even use #send.


 
Reply With Quote
 
Giles Bowkett
Guest
Posts: n/a
 
      06-22-2007
> Don't use eval. There is no need in this example.

Why's everyone so scared of eval? Yes it can destroy your system
completely and forever, but life's short. Might as well enjoy it.
Drive without your seat belt. Go to wild parties. Use eval().

Nobody on their deathbed will ever say "I wish I'd never used eval()."

> CHALLENGE: rewrite the above code to not use eval at all. For that
> matter, don't even use #send.


Aargh! Must rise to challenge!

I tried with write_attribute and failed. I can do it with
instance_eval but that's just a loophole.

On my blog Marcel Molina Jr. pointed out you can use

x.attributes = y.attributes

That's almost an answer to the challenge, but Pat Maddox pointed out
it won't cover protected attributes.

(e.g., attr_protected :some_attribute)

Pat also wrote up the send version. Haven't tested it but it looks solid.

(http://gilesbowkett.blogspot.com/200...rd-models.html)

Anyway, so far, this challenge has kicked my butt. But I'm not giving up yet!

--
Giles Bowkett

Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org

 
Reply With Quote
 
Giles Bowkett
Guest
Posts: n/a
 
      06-22-2007
> > CHALLENGE: rewrite the above code to not use eval at all. For that
> > matter, don't even use #send.


original_obj.attributes.each{|attr, value|
new_obj.update_attribute(attr.to_sym, value)}

--
Giles Bowkett

Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org

 
Reply With Quote
 
Giles Bowkett
Guest
Posts: n/a
 
      06-22-2007
> > CHALLENGE: rewrite the above code to not use eval at all. For that
> > matter, don't even use #send.

>
> original_obj.attributes.each{|attr, value|
> new_obj.update_attribute(attr.to_sym, value)}


prettier:

original_obj.attributes.each do |attr, value|
new_obj.update_attribute(attr.to_sym, value)
end

--
Giles Bowkett

Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org

 
Reply With Quote
 
Xavier Noria
Guest
Posts: n/a
 
      06-22-2007
On Jun 22, 2007, at 10:30 PM, Giles Bowkett wrote:

>> > CHALLENGE: rewrite the above code to not use eval at all. For that
>> > matter, don't even use #send.

>>
>> original_obj.attributes.each{|attr, value|
>> new_obj.update_attribute(attr.to_sym, value)}

>
> prettier:
>
> original_obj.attributes.each do |attr, value|
> new_obj.update_attribute(attr.to_sym, value)
> end


You don't even need #to_sym . Note that rewrite has the side-
effect of actually saving those attributes of new_object in the
database, whereas the original assignments didn't. Perhaps that's OK
though.

-- fxn




 
Reply With Quote
 
Giles Bowkett
Guest
Posts: n/a
 
      06-22-2007
> > original_obj.attributes.each do |attr, value|
> > new_obj.update_attribute(attr.to_sym, value)
> > end

>
> You don't even need #to_sym . Note that rewrite has the side-
> effect of actually saving those attributes of new_object in the
> database, whereas the original assignments didn't. Perhaps that's OK
> though.


Well, if you've got validation callbacks (e.g.
validates_uniqueness_of) this version could blow up on that. That's
assuming you're copying objects of the same class as one another - I
originally came up with this to copy things of different classes
(near-identical subclasses of an as-yet-unconstructed abstract
superclass).

Also - I didn't realize these methods came from ActiveSupport. Doh.
The original ran in pure Ruby without Rails - it'd probably be ideal
to implement the solution in pure Ruby.

--
Giles Bowkett

Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org

 
Reply With Quote
 
Xavier Noria
Guest
Posts: n/a
 
      06-22-2007
On Jun 23, 2007, at 12:06 AM, Giles Bowkett wrote:

>> > original_obj.attributes.each do |attr, value|
>> > new_obj.update_attribute(attr.to_sym, value)
>> > end

>>
>> You don't even need #to_sym . Note that rewrite has the side-
>> effect of actually saving those attributes of new_object in the
>> database, whereas the original assignments didn't. Perhaps that's OK
>> though.

>
> Well, if you've got validation callbacks (e.g.
> validates_uniqueness_of) this version could blow up on that.


Not really, update_attribute() bypasses validations by default, it's
written like this:

send(name.to_s + '=', value)
save(false)

> Also - I didn't realize these methods came from ActiveSupport. Doh.
> The original ran in pure Ruby without Rails - it'd probably be ideal
> to implement the solution in pure Ruby.


Yeah, except for the call to attributes(), which is a Railism. In
fact I thought this thread belonged to the Rails mailing list because
of that.

-- fxn




 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Replacement components on a Cisco 2611 mainboard (router go boom) Mike Cisco 1 06-16-2006 02:36 PM
Recommendation for wired/usb/bluetooth headset slim mic boom? Tim UK VOIP 1 02-19-2006 04:42 PM
Help needed choosing a boom for lighting kasterborus@yahoo.com Digital Photography 1 11-16-2005 05:42 PM
Hawaii Boom Town In Real Estate christopher ratliff Computer Support 0 01-04-2005 04:35 AM
DVD players boom wly1017 DVD Video 0 11-22-2004 12:07 AM



Advertisments