# Default values for method arguments

**URL:** <https://www.ruby-forum.com/t/default-values-for-method-arguments/78519>\
**Category:** Ruby\
**Created:** [December 6, 2006, 3:05pm UTC](https://www.ruby-forum.com/t/default-values-for-method-arguments/78519 "2006-12-06T15:05:37Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [December 6, 2006, 3:05pm UTC](https://www.ruby-forum.com/t/default-values-for-method-arguments/78519/1 "2006-12-06T15:05:37Z")

</div>

Hi all,

Probably I’m trying something impossible, but when giving default  
values for arguments to a method call, do I have to give default-values  
for _all_ arguments?

irb(main):001:0\> class A  
irb(main):002:1\> def a(b = 0, c, d = ‘’, e)  
irb(main):003:2\> puts b, c, d, e  
irb(main):004:2\> end  
irb(main):005:1\> end  
SyntaxError: compile error  
(irb):2: syntax error  
def a(b = 0, c, d = ‘’, e)  
^  
(irb):2: syntax error  
(irb):5: syntax error  
from (irb):5

And also when giving default-values to all arguments, omitting  
arguments when calling the method doesn’t seem to be a succes:

irb(main):001:0\> class B  
irb(main):002:1\> def b(c = 0, d = 1, e = 2)  
irb(main):003:2\> puts c, d, e  
irb(main):004:2\> end  
irb(main):005:1\> end  
=\> nil  
irb(main):006:0\> B.new.b(1,2,3)  
1  
2  
3  
=\> nil  
irb(main):007:0\> B.new.b(1,3)  
SyntaxError: compile error  
(irb):7: syntax error  
B.new.b(1,3)  
^  
from (irb):7

Is it impossible or I’m I just coding it wrong?

Cheers,  
Paul

---

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [December 6, 2006, 3:19pm UTC](https://www.ruby-forum.com/t/default-values-for-method-arguments/78519/2 "2006-12-06T15:19:39Z")

</div>

On Dec 6, 2006, at 8:05 AM, paul wrote:

> Probably I’m trying something impossible, but when giving default  
> values for arguments to a method call, do I have to give default-  
> values  
> for _all_ arguments?

No, but all the arguments that don’t have defaults must come before  
(to the left of) those that do.

> 1  
> 2  
> 3  
> =\> nil  
> irb(main):007:0\> B.new.b(1,3)  
> SyntaxError: compile error  
> (irb):7: syntax error  
> B.new.b(1,3)  
> ^  
> from (irb):7

Again, you can only leave out arguments that come after (to the right  
of) those you provide.

> Is it impossible or I’m I just coding it wrong?

You just need to switch strategies. Use Ruby’s simulated keyword  
arguments for something like this:

> > def test(args)  
> > puts args.values\_at(:a, :b, :c)  
> > end  
> > =\> nil
> 
> > test :a =\> 1, :c =\> 2  
> > 1  
> > nil  
> > 2  
> > =\> nil

Hope that helps.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [December 6, 2006, 4:31pm UTC](https://www.ruby-forum.com/t/default-values-for-method-arguments/78519/3 "2006-12-06T16:31:47Z")

</div>

> 2  
> =\> nil

Hi James,

The Simulated Keyword Arguments you talk about are a little abstract to  
me, but I think I get the idea. I suppose in the example above I would  
have to add a couple of lines to define the default values…  
This way, the general idea is the same as the following?

irb(main):001:0\> def test(args)  
irb(main):002:1\> args[‘a’] = ‘defaultA’ unless args.has\_key?(‘a’)  
irb(main):003:1\> args[‘b’] = ‘defaultB’ unless args.has\_key?(‘b’)  
irb(main):004:1\> args[‘c’] = ‘defaultC’ unless args.has\_key?(‘c’)  
irb(main):005:1\> puts args.indexes(‘a’, ‘b’, ‘c’)  
irb(main):006:1\> end  
=\> nil  
irb(main):007:0\> test({‘a’ =\> ‘someA’, ‘c’ =\> ‘someC’})  
(irb):5: warning: Hash#indexes is deprecated; use Hash#values\_at  
someA  
defaultB  
someC  
=\> nil

An additional question: do you know a link where I can find more on  
those Simulated Keyword Arguments? I did some googling, but it turned  
up with nothing on:  
ruby “Simulated Keyword Arguments”

Those colons you use before the variable-names are a little like magic  
to me. (though I checked, without those colons, you’re example above  
wouldn’t have worked…) 🙂

Cheers,  
Paul

---

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [December 6, 2006, 4:47pm UTC](https://www.ruby-forum.com/t/default-values-for-method-arguments/78519/4 "2006-12-06T16:47:49Z")

</div>

On Dec 6, 2006, at 9:30 AM, paul wrote:

> The Simulated Keyword Arguments you talk about are a little  
> abstract to  
> me, but I think I get the idea.

My fault, I did not describe them very well. Here are the critical  
bits of information:

If a method call ends with some arguments that look like a Hash  
definition (using the fat arrows =\>), Ruby collects those and passes  
a single Hash to the method in their place. You can then work with  
the Hash normally.

> defaultB  
> someC  
> =\> nil

Another way to set defaults:

> > def test(args)  
> > args = { “a” =\> “default a”,  
> > ?\> “b” =\> “default b”,  
> > ?\> “c” =\> “default c” }.merge(args)  
> > puts args.values\_at(“a”, “b”, “c”)  
> > end  
> > =\> nil  
> > test “a” =\> “some a”, “c” =\> “some c”  
> > some a  
> > default b  
> > some c  
> > =\> nil

> An additional question: do you know a link where I can find more on  
> those Simulated Keyword Arguments?

See Collecting Hash Arguments at the bottom of:

[http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut\_methods.html](http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_methods.html)

> Those colons you use before the variable-names are a little like magic  
> to me. (though I checked, without those colons, you’re example above  
> wouldn’t have worked…) 🙂

Those are just Symbol objects. Don’t lose too much sleep over them  
yet, as you can see from the new example Strings work fine too.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [December 6, 2006, 6:13pm UTC](https://www.ruby-forum.com/t/default-values-for-method-arguments/78519/5 "2006-12-06T18:13:15Z")

</div>

On Thu, 7 Dec 2006, Ken B. wrote:

> Try this-- it’s more concise, and you probably won’t feel the need  
> for more syntactic magic after that.
> 
> def test(args)  
> args[:a] ||= ‘defaultA’  
> args[:b] ||= ‘defaultB’  
> args[:c] ||= ‘defaultC’  
> puts args.indexes(:a, :b, :c)  
> end

but this breaks

test :a =\> false

as does this

test :a =\> nil

and this

test ‘a’ =\> true

regards.

-a

---

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [December 8, 2006, 9:24am UTC](https://www.ruby-forum.com/t/default-values-for-method-arguments/78519/6 "2006-12-08T09:24:06Z")

</div>

Ken B. wrote:

> Try this-- it’s more concise, and you probably won’t feel the need  
> for more syntactic magic after that.
> 
> def test(args)  
> args[:a] ||= ‘defaultA’  
> args[:b] ||= ‘defaultB’  
> args[:c] ||= ‘defaultC’  
> puts args.indexes(:a, :b, :c)  
> end

I find:

def test(args)  
realargs = {:a =\> ‘defaultA’,  
:b =\> ‘defaultB’,  
:c =\> ‘defaultC’}.update(args)

puts args.indexes(:a, :b, :c)  
end

more readable. Preferrably extracting the default values into constants  
before the method definition and (deep?)cloning the hash.

Also, your code clobbers the hash put into args by putting in values.  
This might not cause bugs most of the case, but might in case someone  
passes in an actual hash, so I’d just stay on the safe side.

David V.

---

<div class="post-metadata">

**Author:** ![paul](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/bbe5ce/32.png) [@paul](https://www.ruby-forum.com/u/paul)\
**Post date:** [December 6, 2006, 4:55pm UTC](https://www.ruby-forum.com/t/default-values-for-method-arguments/78519/7 "2006-12-06T16:55:51Z")

</div>

On Wed, 06 Dec 2006 07:27:00 -0800, paul wrote:

> > 2  
> > irb(main):003:1\> args[‘b’] = ‘defaultB’ unless args.has\_key?(‘b’)  
> > irb(main):004:1\> args[‘c’] = ‘defaultC’ unless args.has\_key?(‘c’)  
> > irb(main):005:1\> puts args.indexes(‘a’, ‘b’, ‘c’)  
> > irb(main):006:1\> end  
> > =\> nil  
> > irb(main):007:0\> test({‘a’ =\> ‘someA’, ‘c’ =\> ‘someC’})  
> > (irb):5: warning: Hash#indexes is deprecated; use Hash#values\_at  
> > someA  
> > defaultB  
> > someC  
> > =\> nil

Try this-- it’s more concise, and you probably won’t feel the need  
for more syntactic magic after that.

def test(args)  
args[:a] ||= ‘defaultA’  
args[:b] ||= ‘defaultB’  
args[:c] ||= ‘defaultC’  
puts args.indexes(:a, :b, :c)  
end

> An additional question: do you know a link where I can find more on  
> those Simulated Keyword Arguments? I did some googling, but it turned  
> up with nothing on:  
> ruby “Simulated Keyword Arguments”
> 
> Those colons you use before the variable-names are a little like magic  
> to me. (though I checked, without those colons, you’re example above  
> wouldn’t have worked…) 🙂

The colons make them into symbol objects.
