From: yermej on
On Jul 11, 2:57 pm, Alex Stahl <ast...(a)hi5.com> wrote:
[...]
> Problem is that 'call['params']' is treated as a string by the receiver,
> not the hash I intended to pass.  Tried using casting operations first,
> like .to_s and then .to_hash, but the to_hash call fails w/ no method
> error.  Instead the hash comes through as a string.  How can I pass it
> so that it remains a hash, and retains its structure for key/val reading
> in the receiver?
>

This will do it:

eval("#{call['action']}(call['params'])")

Depending on context, you can probably completely avoid using eval:

method(call['action']).call(call['params'])

When you use #{call['params']}, I think that calls #to_s on the Hash
which causes what you're seeing.

Jeremy
From: Brian Candler on
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.
--
Posted via http://www.ruby-forum.com/.

From: David A. Black on
Hi --

On Mon, 12 Jul 2010, 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.

Footnote: in 1.9, Hash#to_s has changed such that (like Array#to_s) it
returns more of an inspect string:

>> puts "#{call['action']}(#{call['params']})"
someFunc({"a"=>"foo", "b"=>"bar", "c"=>"etc"})

(I concur however in your point that send is almost certainly a better
choice anyway.)


David

--
David A. Black, Senior Developer, Cyrus Innovation Inc.

The Ruby training with Black/Brown/McAnally
Compleat Stay tuned for next event announcement!
Rubyist http://www.compleatrubyist.com

From: Alex Stahl on
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?

-Alex

On Sun, 2010-07-11 at 16:05 -0500, yermej wrote:
> On Jul 11, 2:57 pm, Alex Stahl <ast...(a)hi5.com> wrote:
> [...]
> > Problem is that 'call['params']' is treated as a string by the receiver,
> > not the hash I intended to pass. Tried using casting operations first,
> > like .to_s and then .to_hash, but the to_hash call fails w/ no method
> > error. Instead the hash comes through as a string. How can I pass it
> > so that it remains a hash, and retains its structure for key/val reading
> > in the receiver?
> >
>
> This will do it:
>
> eval("#{call['action']}(call['params'])")
>
> Depending on context, you can probably completely avoid using eval:
>
> method(call['action']).call(call['params'])
>
> When you use #{call['params']}, I think that calls #to_s on the Hash
> which causes what you're seeing.
>
> Jeremy
>



From: Ammar Ali on
[Note: parts of this message were removed to make it a legal post.]

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