From: Alex Stahl on 11 Jul 2010 18:50 Thanks again, yermej's suggestion actually worked out. I've now got send doing exactly what I wanted to accomplish. Going into my thinking on this problem, I knew I wanted dynamic execution, and being relatively new to ruby, thought that eval would be the right tool. Wasn't aware of send. Great thing is it caused me to look up the Object and see all the cool things it can do for me. So my original question probably should have been, "is eval even the right tool for this?". Of course, that's not always obvious considering there's always more than one way to do something in ruby. On Sun, 2010-07-11 at 16:58 -0500, Ammar Ali wrote: > On Mon, Jul 12, 2010 at 12:41 AM, Alex Stahl <astahl(a)hi5.com> wrote: > > > Thanks. You're actually the second response to suggest doing it that > > way (w/ eval). But it doesn't work for me. > > > > Though, the first respondent is using 1.9.1, and I've got 1.8.7 at the > > moment. Are you by chance also on 1.9.1? > > > On 1.8.7 use yermej's suggestion, without the interpolation, if you choose > to stick with eval despite the excellent suggestions to use send instead: > > eval("#{call['action']}(call['params'])") > > Cheers, > Ammar
From: Brian Candler on 12 Jul 2010 04:54 Alex Stahl wrote: > So my original question probably should have been, "is eval even the > right tool for this?". Of course, that's not always obvious considering > there's always more than one way to do something in ruby. Certainly. You should also be aware that 'send' is also not without its security problems: $ irb --simple-prompt >> RUBY_DESCRIPTION => "ruby 1.8.7 (2010-01-10 patchlevel 249) [x86_64-linux]" >> foo = "system" => "system" >> bar = "rm /tmp/nonexistent*" => "rm /tmp/nonexistent*" >> send(foo,bar) rm: cannot remove `/tmp/nonexistent*': No such file or directory => false $ irb19 --simple-prompt >> RUBY_DESCRIPTION => "ruby 1.9.2dev (2009-07-18 trunk 24186) [i686-linux]" >> foo = "system" => "system" >> bar = "rm /tmp/nonexistent*" => "rm /tmp/nonexistent*" >> send(foo,bar) rm: cannot remove `/tmp/nonexistent*': No such file or directory => false So it may be a good idea to give all your callable methods a prefix ("do_xxx"), and/or only call public methods: send(foo,bar) if respond_to?(foo) -- Posted via http://www.ruby-forum.com/.
From: Robert Klemme on 12 Jul 2010 12:22 On 11.07.2010 23:00, Brian Candler wrote: > Just use 'puts' instead of 'eval' to see what's happening. > >>> json =<<EOS > { > "action": "someFunc", > "params": { > "a": "foo", > "b": "bar", > "c": "etc" > } > } > EOS > => "{\n \"action\": \"someFunc\",\n \"params\": {\n \"a\": > \"foo\",\n \"b\": \"bar\",\n \"c\": \"etc\"\n }\n}\n" >>> require 'rubygems' > => true >>> require 'json' > => true >>> call = JSON.parse(json) > => {"action"=>"someFunc", "params"=>{"a"=>"foo", "b"=>"bar", > "c"=>"etc"}} >>> puts "#{call['action']} #{call['params']}" > someFunc afoobbarcetc > => nil >>> puts "#{call['action']}('#{call['params']}')" > someFunc('afoobbarcetc') > => nil >>> > > Should be pretty obvious now, remember that eval is just interpreting > that string as a piece of ruby code. I wouldn't even use eval here - it's unsafe and slow. Something like this should work send(call['action'], *call['params']) Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
From: Josh Cheek on 12 Jul 2010 14:30 [Note: parts of this message were removed to make it a legal post.] Eval is also a wonky work flow. You have data serialized as JSON in a String You parse it into a Ruby hash You then serialize it as Ruby code in a String You then eval the string to get the hash back out of it... I don't know what types JSON supports, but if it supports anything that doesn't have a literal, then that second converting to String and evaling will break. Also explains why Amir's solution breaks on 1.8, because, as David A. Black pointed out, Hash#to_s changed, and that is what is being used to serialize it (which implies to me that this may not be realized) mini:~ ammar$ rvm use 1.9.1 info: Using ruby 1.9.1 p378 mini:~ ammar$ irb ruby-1.9.1-p378 > require 'json' => true ruby-1.9.1-p378 > def some_func(hash); puts "from function: #{hash.inspect}"; end => nil ruby-1.9.1-p378 > j = '{ "action": "some_func", "params": { "a": "foo", "b": "bar" } }' => "{ \"action\": \"some_func\", \"params\": { \"a\": \"foo\", \"b\": \"bar\" } }" ruby-1.9.1-p378 > call = JSON.parse(j) => {"action"=>"some_func", "params"=>{"a"=>"foo", "b"=>"bar"}} ruby-1.9.1-p378 > eval("#{call['action']}(#{ call['params']})") from function: {"a"=>"foo", "b"=>"bar"} => nil
First
|
Prev
|
Pages: 1 2 3 Prev: Basic Question: How do you check to see if gets is a num Next: hash example |