When you write:
def cost(*orders)
end
then all the parameters passed to the cost
method will be put into a single array named orders
. These two are thus equivalent:
def cost(*orders)
p orders.class #=> Array
p orders #=> [1,2,3]
end
cost(1,2,3)
def cost(orders)
p orders.class #=> Array
p orders #=> [1,2,3]
end
cost( [1,2,3] ) # note the array literal brackets
In your case, when you remove the "splat" you are saying "set orders
to reference whatever was passed in directly". In this case you're passing it a Hash, and when you iterate a hash you get key/value pairs for each entry. This is just what you want.
When you do have the splat, though, you're getting this:
def cost(*orders)
p orders.class #=> Array
p orders #=> [{:rice=>1, :noodles=>1}]
end
orders = {:rice=>1, :noodles=>1}
cost(orders)
So you're wrapping your hash in an array, and then iterating over the elements of the array. Thus, the first value passed to the block is the entire hash, and there is no second parameter.
def cost(*orders)
p orders.class #=> Array
p orders #=> [{:rice=>1, :noodles=>1}]
orders.each do |item,number|
p item #=> {:rice=>1, :noodles=>1}
p number #=> nil
end
end
orders = {:rice=>1, :noodles=>1}
cost(orders)
At this point you can't multiply anything by nil
and so your code breaks.