Forum: Ruby hash as paramerter container

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Schüle Daniel (Guest)
on 2006-01-09 15:54
(Received via mailing list)
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>
James G. (Guest)
on 2006-01-09 16:05
(Received via mailing list)
On Jan 9, 2006, at 7:53 AM, Schüle Daniel wrote:

> >>>
> >>> 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
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 G. II
Robert K. (Guest)
on 2006-01-09 18:58
(Received via mailing list)
Schüle Daniel wrote:
>  >>>
> irb(main):017:0> def foo a,b,c
>
>
> 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
        from :0

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
Adam S. (Guest)
on 2006-01-09 19:37
(Received via mailing list)
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
This topic is locked and can not be replied to.