Hash as paramerter container

Hello all,

I am looking for Ruby equivalent for this Python Code

>>> def foo(a,b,c):
.... print "a is ", a
.... print "b is ", b
.... print "c is ", c
....
>>> h = {"c":3, "a":1, "b":2}
>>>
>>> foo
<function foo at 0x403d6f7c>
>>> foo(**h)
a is 1
b is 2
c is 3

my first try

=> {"c"=>333, :b=>2, :a=>1}
irb(main):017:0> def foo a,b,c
irb(main):018:1> puts "a is #{a}"
irb(main):019:1> puts "b is #{b}"
irb(main):020:1> puts "c is #{c}"
irb(main):021:1> end
=> nil
irb(main):022:0> foo *h
a is c333
b is b2
c is a1
=> nil

this seem to replace (or substituate) the parameters expected by foo
in the order of hash. And since hash has no order (in both languages) it's a random replacement.

Is there a trick I don't know about?

Regards, Daniel

ps:

The case of unpacking an array seem to be 1:1 mapping betweeen Python and Ruby.

>>> n = [1,2,3]
>>>
>>> def bar(*args):
.... for i in args:
.... print i
....
>>> bar(*n)
1
2
3
>>>
>>> bar(1,2,3)
1
2
3
>>>

irb(main):065:0> def bar *args
irb(main):066:1> args.each {|i| puts i}
irb(main):067:1> end
=> nil
irb(main):068:0> n = [1,2,3]
=> [1, 2, 3]
irb(main):069:0> bar(*n)
1
2
3
=> [1, 2, 3]
irb(main):070:0> bar(1,2,3)
1
2
3
=> [1, 2, 3]
irb(main):071:0>

Hello all,

I am looking for Ruby equivalent for this Python Code

>>> def foo(a,b,c):
.... print "a is ", a
.... print "b is ", b
.... print "c is ", c
....
>>> h = {"c":3, "a":1, "b":2}
>>>
>>> foo
<function foo at 0x403d6f7c>
>>> foo(**h)
a is 1
b is 2
c is 3

Here are some ideas:

>> def show( a, b, c)
>> puts "a is #{a}"
>> puts "b is #{b}"
>> puts "c is #{c}"
>> end
=> nil
>> params = {:a => 1, :b => 2, :c => 3}
=> {:b=>2, :c=>3, :a=>1}
>> show(*params.values_at(:a, :b, :c))
a is 1
b is 2
c is 3
=> nil

That's about the closet I can get what what you posted, I think.

>> def show( args )
>> [:a, :b, :b].each { |key| puts "#{key} is #{args[key]}" }
>> end
=> nil
>> show(:a => 1, :b => 2, :c => 3)
a is 1
b is 2
=> [:a, :b, :b]

This one is more Rubyish though, to me. It uses Ruby's almost named parameter syntax.

Hope that gives you some new ideas.

James Edward Gray II

···

On Jan 9, 2006, at 7:53 AM, Schüle Daniel wrote:

Schüle Daniel wrote:

Hello all,

I am looking for Ruby equivalent for this Python Code

>>> def foo(a,b,c):
... print "a is ", a
... print "b is ", b
... print "c is ", c
...
>>> h = {"c":3, "a":1, "b":2}
>>>
>>> foo
<function foo at 0x403d6f7c>
>>> foo(**h)
a is 1
b is 2
c is 3

my first try

=> {"c"=>333, :b=>2, :a=>1}
irb(main):017:0> def foo a,b,c
irb(main):018:1> puts "a is #{a}"
irb(main):019:1> puts "b is #{b}"
irb(main):020:1> puts "c is #{c}"
irb(main):021:1> end
=> nil
irb(main):022:0> foo *h
a is c333
b is b2
c is a1
=> nil

this seem to replace (or substituate) the parameters expected by foo
in the order of hash. And since hash has no order (in both languages)
it's a random replacement.

Is there a trick I don't know about?

I don't know Python but I assume that foo(**h) assigns hash entries to
function arguments. Ruby cannot do this because parameter names are lost
at runtime. Here's what you can do:

def foo(*a)
  case a.length
    when 1
      a[0].each {|k,v| puts "#{k} is #{v}"}
    when 3
      puts "a is #{a[0]}"
      puts "b is #{a[1]}"
      puts "c is #{a[2]}"
    else
      raise ArgumentError, "wrong number of arguments"
  end
end

foo(1,2,3)

a is 1
b is 2
c is 3
=> nil

foo(:x=>1, :y=>32, :z=>4)

y is 32
z is 4
x is 1
=> {:y=>32, :z=>4, :x=>1}

foo(1,2,3,4)

RuntimeError: Illegal Call
        from (irb):24:in `foo'
        from (irb):29

But generally you would decide whether you use a hash or individual
parameters. You could go through some hoops to retrofit something on Ruby
that will behave approximately like Python does but I won't be fast or
elegant and I guess there would be some limitations. But Ruby 2 is will
introduce new functionality here (named parameters / arguments); it might
then be possible to do what you know from Python.

HTH

Kind regards

    robert

···

from :0

What about

irb(main):033:0> h = {:c=>333,:b=>2, :a=>1}
=> {:c=>333, :a=>1, :b=>2}
irb(main):034:0> def foo h
irb(main):035:1> puts "a is #{h[:a]}"
irb(main):036:1> puts "b is #{h[:b]}"
irb(main):037:1> puts "c is #{h[:c]}"
irb(main):038:1> end
=> nil
irb(main):039:0> foo h
a is 1
b is 2
c is 333
=> nil

···

Schüle Daniel wrote:
> Hello all,
>
> I am looking for Ruby equivalent for this Python Code
>
> >>> def foo(a,b,c):
> ... print "a is ", a
> ... print "b is ", b
> ... print "c is ", c
> ...
> >>> h = {"c":3, "a":1, "b":2}
> >>>
> >>> foo
> <function foo at 0x403d6f7c>
> >>> foo(**h)
> a is 1
> b is 2
> c is 3
>
> my first try
>
> => {"c"=>333, :b=>2, :a=>1}
> irb(main):017:0> def foo a,b,c
> irb(main):018:1> puts "a is #{a}"
> irb(main):019:1> puts "b is #{b}"
> irb(main):020:1> puts "c is #{c}"
> irb(main):021:1> end
> => nil
> irb(main):022:0> foo *h
> a is c333
> b is b2
> c is a1
> => nil
>
>
> this seem to replace (or substituate) the parameters expected by foo
> in the order of hash. And since hash has no order (in both languages)
> it's a random replacement.
>
> Is there a trick I don't know about?