Accepting or Passing a Variable Number of Arguments


You want to write a method that can accept any number of arguments. Or maybe you want to pass the contents of an array as arguments into such a method, rather than passing in the array itself as a single argument.


To accept any number of arguments to your method, prefix the last argument name with an asterisk. When the method is called, all the "extra" arguments will be collected in a list and passed in as that argument:

	def sum(*numbers)
	 puts "I'm about to sum the array #{numbers.inspect}"
	 numbers.inject(0) { |sum, x| sum += x }

	sum(1, 2, 10)
	# I'm about to sum the array [1, 2, 10]
	# => 13

	sum(2, -2, 2, -2, 2, -2, 2, -2, 2)
	# I'm about to sum the array [2, -2, 2, -2, 2, -2, 2, -2, 2]
	# => 2
	# I'm about to sum the array []
	# => 0

To pass an array of arguments into a method, use the asterisk signifier before the array you want to be turned into "extra" arguments:

	to_sum = []
	1.upto(10) { |x| to_sum << x }
	# I'm about to sum the array [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
	# => 55

Bad things happen if you forget the asterisk: your entire array is treated as a single "extra" argument:

	# I'm about to sum the array [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
	# TypeError: Array can't be coerced into Fixnum



Why make a method take a variable number of arguments, instead of just having it take a single array? It's basically for the convenience of the user. Consider the Kernel#printf method, which takes one fixed argument (a format string), and then a variable number of inputs to the format string:

	printf('%s | %s', 'left', 'right')
	# left | right

It's very rare that the caller of printf already has her inputs lying around in an array. Fortunately, Ruby is happy to create the array on the user's behalf. If the caller does already have an array of inputs, it's easy to pass the contents of that array as "extra" arguments by sticking the asterisk onto the appropriate variable name:

	inputs = ['left', 'right']
	printf('%s | %s', *inputs)
	# left | right

As you can see, a method can take a fixed number of "normal" arguments and then a variable number of "extra" arguments. When defining such a method, just make sure that the last argument is the one you prefix with the asterisk:

	def format_list(header, footer='', *data)
	 puts header
	 puts (line = '-' * header.size)
	 puts data.join("
	 puts line
	 puts footer
	cozies = 21
	gaskets = 10
	format_list("Yesterday's productivity numbers:", 'Congratulations!',
	 "#{cozies} slime mold cozies", "#{gaskets} Sierpinski gaskets")
	# Yesterday's productivity numbers:
	# --------------------------------
	# 21 slime mold cozies
	# 10 Sierpinski gaskets
	# --------------------------------
	# Congratulations!

You can use the asterisk trick to call methods that don't take a variable number of arguments. You just need to make sure that the array you're using has enough elements to provide values for all of the method's required arguments.

You'll find this especially useful for constructors that take many arguments. The following code initializes four Range objects from four arrays of constructor arguments:

	 ranges = [[1, 10], [1, 6, true], [25, 100, false], [6, 9]]
	 ranges.collect { |l|*l) }
	 # => [1..10, 1…6, 25..100, 6..9]



Date and Time



Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming


Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration

Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399 © 2008-2020.
If you may any questions please contact us: