An introduction to the stuff your mom and dad didn't tell you about giving arguments to methods.
The asterisk
Capture x amount of arguments.
def silly_list(*args)
args.join(' ') + '.'
end
silly_list 'My', 'hovercraft', 'is', 'full', 'of', 'eels'
"My hovercraft is full of eels."
You can also do it the other way around, when calling a method. This will pass each item in the array as a separate argument to the method.
def say_a_name(first, last)
puts "#{last}, #{first}"
end
name = ['John', 'McClaine']
say_a_name(*name)
# => "McClaine, John"
name = ['John', 'Leethal', 'McClaine']
say_a_name(*name)
# => ArgumentError: wrong number of arguments (3 for 2)
The ampersand
Capture the block.
def can_has_block(&block)
puts block.inspect
end
can_has_block
# => nil
can_has_block { "Here is a block" }
# => #<Proc:0x0008f138@-:8>
You can also do it the other way around, when calling a method. This will pass the proc to the method as if you were giving it a normal block. The last two calls are identical:
a_proc = Proc.new { puts "I am a proc" }
def call_the_block
yield
end
call_the_block { puts "I am a block" }
# => I am a block
call_the_block { a_proc.call }
# => "I am a proc"
call_the_block(&a_proc)
# => "I am a proc"
And then, of course, without the ampersand Ruby treats the proc as any other object passed as an argument.
call_the_block(a_proc)
# => ArgumentError: wrong number of arguments (1 for 0)
Both?
Of course! Let's use every trick in the book.
def another_map(*args, &block)
args.map(&block)
end
another_map('hello', 'there') {|i| i.upcase }
# => ["HELLO", "THERE"]
Yield
Don't forget yield, though. These two calls are identical.
def say_hello(&block)
block.call
end
def say_hello
yield
end
In fact, yield
is much better, as Ruby doesn't have to instantize a Proc
object.
Default values
You probably knew this already.
def a_default_value(value = {})
value
end
a_default_value
# => {}
a_default_value("hello!")
# => "hello!"