Forum: Ruby Optional arguments and default values

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.
73803e9b62fe9b6499db6a7ca87c909c?d=identicon&s=25 Surgeon (Guest)
on 2005-12-31 12:51
(Received via mailing list)
Hi,

How do I give a method optional arguments and default values?

Exmpl:

foo is a function that multiplies all of its arguments together. If
there is not any argument, a default value of "qwerty" returns.

foo(2,3)    ---->  6
foo(2,3,5) ----> 30
foo(2,3,5,2) -> 60

foo() -----------> "qwerty"
82e62c756d89bc6fa0a0a2d7f2b1e617?d=identicon&s=25 Ross Bamford (Guest)
on 2006-01-01 21:32
(Received via mailing list)
On Fri, 30 Dec 2005 19:59:05 -0000, Surgeon <biyokuantum@gmail.com>
wrote:

> foo(2,3,5) ----> 30
> foo(2,3,5,2) -> 60
>
> foo() -----------> "qwerty"
>

Maybe:
	def foo(*args)
	  args.empty? && "qwerty" or args.inject(0) { |s,i| s * i }
	end

or:

	def foo(*args)
	  if args.empty?
	    "qwerty"
	  else
	    args.inject(0) { |s,i| s * i }
	  end
	end

Default values are slightly different:

	def sum(v1 = 10, v2 = 5)
	  v1 + v2
	end

Once you give a default value to an arg, you must also give defaults to
all following args (except any &block arg).

Defaults don't have to be literal - you can use anything

	def foo(arg = somemethod('c')) ... end

even another arg

	def foo(a1, a2 = a1) ... end

I believe they're evaluated in the scope of the method itself. It's
quite
cool.

Cheers,
5befe95e6648daec3dd5728cd36602d0?d=identicon&s=25 Robert Klemme (Guest)
on 2006-01-01 21:32
(Received via mailing list)
Ross Bamford <rosco@roscopeco.remove.co.uk> wrote:
>>
> end
>
> or:
>
> def foo(*args)
>   if args.empty?
>     "qwerty"
>   else
>     args.inject(0) { |s,i| s * i }
>   end
> end

The implementation of Enumerable#inject allows for an even more elegant
solution

def foo(*args)
  args.inject {|a,b| a*b} || "qwerty"
end

>> foo 2,3,5
=> 30
>> foo 2,3
=> 6
>> foo 2
=> 2
>> foo
=> "qwerty"

Note: if args is empty this inject returns nil, if there is just one
element
that is returned.

Another solution would be to implement things like this in Enumerable:

module Enumerable
  def sum()     inject(0) {|a,b| a+b} end
  def product() inject(1) {|a,b| a*b} end
end

or

module Enumerable
  def sum()     inject {|a,b| a+b} end
  def product() inject {|a,b| a*b} end
end

Allowing for invocations like these

>> [1,2,3,4].sum
=> 10
>> (1..4).sum
=> 10
>> (1...5).sum
=> 10
>> (1..10).map { rand 20 }.sum
=> 91

Kind regards

    robert
82e62c756d89bc6fa0a0a2d7f2b1e617?d=identicon&s=25 Ross Bamford (Guest)
on 2006-01-01 21:32
(Received via mailing list)
On Sat, 31 Dec 2005 12:58:14 -0000, Robert Klemme <bob.news@gmx.net>
wrote:

>>     "qwerty"
> end
> Note: if args is empty this inject returns nil, if there is just one
> element that is returned.
>

Cool, I didn't know that, thanks for pointing it out :)

Cheers,
This topic is locked and can not be replied to.