# Passing keyword arguments

**URL:** <https://www.ruby-forum.com/t/passing-keyword-arguments/119092>\
**Category:** Ruby\
**Created:** [November 3, 2007, 1:27am UTC](https://www.ruby-forum.com/t/passing-keyword-arguments/119092 "2007-11-03T01:27:45Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [November 3, 2007, 1:27am UTC](https://www.ruby-forum.com/t/passing-keyword-arguments/119092/1 "2007-11-03T01:27:45Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [November 3, 2007, 9:49am UTC](https://www.ruby-forum.com/t/passing-keyword-arguments/119092/2 "2007-11-03T09:49:41Z")

</div>

On Nov 3, 2007 1:27 AM, Trans [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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

> 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.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [November 4, 2007, 12:09am UTC](https://www.ruby-forum.com/t/passing-keyword-arguments/119092/3 "2007-11-04T00:09:43Z")

</div>

On Nov 3, 4:47 am, “Robert D.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> irb(main):001:0\> def foo \*args
> 
> > def bar(opt, \*args)  
> > foo(\*args, :baz =\> opt) # doesn’t work.
> 
> now it does , almost  
> foo( :baz =\> opt, \*args)

Interesting approach. Thanks.

T.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [November 4, 2007, 1:51am UTC](https://www.ruby-forum.com/t/passing-keyword-arguments/119092/4 "2007-11-04T01:51:24Z")

</div>

On Nov 2, 8:27 pm, removed\_email\_address@domain.invalid wrote:

> def bar(opt, \*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’, :opt1 =\> ‘one’, :opt2 =\> ‘two’  
bar ‘extra’, 4  
bar ‘extra’, 5, ‘bar’, :opt1 =\> ‘one’, :opt2 =\> ‘two’

Brian A.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [November 4, 2007, 1:11am UTC](https://www.ruby-forum.com/t/passing-keyword-arguments/119092/5 "2007-11-04T01:11:23Z")

</div>

Robert D. wrote:

> On Nov 3, 2007 1:27 AM, Trans [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > 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
> 
> > ```
> > ...
> > 
> > ```

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, :other =\> ‘pie’, \*args)  
end

bar(10, 20, 30)

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

{:baz=\>10, :other=\>“pie”}  
[20, 30]

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [November 4, 2007, 1:53am UTC](https://www.ruby-forum.com/t/passing-keyword-arguments/119092/6 "2007-11-04T01:53:45Z")

</div>

On Nov 4, 2007 1:12 AM, 7stud – [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > irb(main):001:0\> def foo \*args  
> > args = args[1…-1]  
> > bar(10, 20, 30)
> 
> –output:–  
> {:baz=\>10}  
> [20, 30]
> 
> {:baz=\>10, :other=\>“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.

---

<div class="post-metadata">

**Author:** ![Trans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/dfb087/32.png) [@Trans](https://www.ruby-forum.com/u/Trans)\
**Post date:** [November 4, 2007, 3:10am UTC](https://www.ruby-forum.com/t/passing-keyword-arguments/119092/7 "2007-11-04T03:10:52Z")

</div>

On Nov 3, 8:50 pm, Brian A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> foo a, b, opts.merge!({:baz =\> opt})  
> end

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

T.
