Passing keyword arguments

T

transfire

Lets say I have a method using the not-so-uncommon keyword options
pattern:

def foo(*args)
opts = (Hash === args.last ? args.pop : {})
...

Now I want to define another method, which is essentially a special
alias, that places a particular option as the first argument:

def bar(opt, *args)
foo(*args, :baz => opt) # doesn't work.
end

Is there no better way to do this than:

def bar(opt, *args)
opts = (Hash === args.last ? args.pop : {})
opts[:baz] = opt
args << opts
foo(*args)
end

Boy, it really makes you wish we had keyword arguments built-in to the
language!!! I forget, will we have those in 1.9? If so how the above
look then?

T.
 
R

robert.dober

Lets say I have a method using the not-so-uncommon keyword options
pattern:

def foo(*args)
opts = (Hash === args.last ? args.pop : {})

Hi Tom

irb(main):001:0> def foo *args
irb(main):002:1> opts, args = args.partition{|x| Hash === x }
irb(main):003:1> opts = opts.inject{ |s,x| s.update x }

seems this should do the trick
...

Now I want to define another method, which is essentially a special
alias, that places a particular option as the first argument:

def bar(opt, *args)
foo(*args, :baz => opt) # doesn't work.

now it does , almost
foo( :baz => opt, *args)

HTH
Robert
end

Is there no better way to do this than:

def bar(opt, *args)
opts = (Hash === args.last ? args.pop : {})
opts[:baz] = opt
args << opts
foo(*args)
end

Boy, it really makes you wish we had keyword arguments built-in to the
language!!! I forget, will we have those in 1.9? If so how the above
look then?
Yes indeed I wished for them for a long time ;)
R.
 
T

transfire

Hi Tom

irb(main):001:0> def foo *args
irb(main):002:1> opts, args = args.partition{|x| Hash === x }
irb(main):003:1> opts = opts.inject{ |s,x| s.update x }

seems this should do the trick




now it does , almost
foo( :baz => opt, *args)

Interesting approach. Thanks.

T.
 
B

bbxx789_05ss

Robert said:
Hi Tom

irb(main):001:0> def foo *args
irb(main):002:1> opts, args = args.partition{|x| Hash === x }
irb(main):003:1> opts = opts.inject{ |s,x| s.update x }

seems this should do the trick

Why not simply:

def foo(*args)
opts = args[0]
args = args[1..-1]

p opts, args
end

def bar(opt, *args)
foo:)baz =>opt, *args)
puts
foo:)baz =>opt, :eek:ther => 'pie', *args)
end

bar(10, 20, 30)


--output:--
{:baz=>10}
[20, 30]

{:baz=>10, :eek:ther=>"pie"}
[20, 30]
 
B

Brian Adkins

Lets say I have a method using the not-so-uncommon keyword options
pattern:

def foo(*args)
opts = (Hash === args.last ? args.pop : {})
...

Now I want to define another method, which is essentially a special
alias, that places a particular option as the first argument:

def bar(opt, *args)
foo(*args, :baz => opt) # doesn't work.
end

Is there no better way to do this than:

def bar(opt, *args)
opts = (Hash === args.last ? args.pop : {})
opts[:baz] = opt
args << opts
foo(*args)
end

Boy, it really makes you wish we had keyword arguments built-in to the
language!!! I forget, will we have those in 1.9? If so how the above
look then?

How flexible do you need to be with the argument handling? Would
something like the following work?

def foo a, b='default', opts={}
puts "a is #{a}, b is #{b}"
opts.each {|k,v| puts "#{k} => #{v}"}
puts '-'*10
end

def bar opt, a, b='default2', opts={}
foo a, b, opts.merge!({:baz => opt})
end

foo 1
foo 2, 'foo'
foo 3, 'foo', :eek:pt1 => 'one', :eek:pt2 => 'two'
bar 'extra', 4
bar 'extra', 5, 'bar', :eek:pt1 => 'one', :eek:pt2 => 'two'

Brian Adkins
 
R

robert.dober

Robert said:
Hi Tom

irb(main):001:0> def foo *args
irb(main):002:1> opts, args = args.partition{|x| Hash === x }
irb(main):003:1> opts = opts.inject{ |s,x| s.update x }

seems this should do the trick

Why not simply:

def foo(*args)
opts = args[0]
args = args[1..-1]

p opts, args
end

def bar(opt, *args)
foo:)baz =>opt, *args)
puts
foo:)baz =>opt, :eek:ther => 'pie', *args)
end

bar(10, 20, 30)


--output:--
{:baz=>10}
[20, 30]

{:baz=>10, :eek:ther=>"pie"}
[20, 30]
because it does not work, try
bar( 1, 2, 3, :a=> 42)
And putting kw params before positionals is too unusual to be likely
to be used a lot :(
my solution is ugly because you have to exactly that but it is at
least hidden from the users of foo and bar.

R.
 
T

transfire

How flexible do you need to be with the argument handling? Would
something like the following work?

def foo a, b='default', opts={}
puts "a is #{a}, b is #{b}"
opts.each {|k,v| puts "#{k} => #{v}"}
puts '-'*10
end

def bar opt, a, b='default2', opts={}
foo a, b, opts.merge!({:baz => opt})
end

Problem is I need *args (an untold amount).

T.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top