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>

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

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:

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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs