There are in fact 4 common ways to pass parameters to a function.
Your first example is the most common one but you made a bad example I'm afraid. Your quantity is always 8, so the if is superfluous, also the parametere price isn't used so also superfluous
This would be the same as the following
def order_food price
"8 large Burgers, coming right up!"
end
But that is not your purpose I presume.
So, it would be something like this
First method
def order_food1(size, quantity, price)
extra = quantity == 1 ? :salad : :Burgers
cost = quantity * price
"#{quantity} #{size} #{extra}, coming right up! Thats is #{cost} dollar please"
end
+ fast (see benchmarks)
+ everybody uses it and understands it in one glace
- you have to know the parameters and the order in which they are defined, you need to read the API for less common uses methods
- you must provide all the parameters
Next: using optional parameters with default values
def order_food2(size = "large", quantity = 1, price = 4)
extra = quantity == 1 ? :salad : :Burgers
cost = quantity * price
"#{quantity} #{size} #{extra}, coming right up! Thats is #{cost} dollar please"
end
+ also widely used
+ no need to use parameters if they are the default ones
- you still need to know the order and meaning of the parameters and if the last is used you need them all
Next: using a hash as parameter
def order_food3(opts = {})
opts = {size: :large, quantity: 1, price: 4}.merge!(opts)
extra = opts[:quantity] == 1 ? :salad : :Burgers
cost = opts[:quantity] * opts[:price]
"#{opts[:quantity]} #{opts[:size]} #{extra}, coming right up! Thats is #{cost} dollar please"
end
- less used, your method self is a little harder to read
- slower
+ no need to know parameters you don't need, nor the order
+ the use of the method is more readable
Next: a simplified version of the previous method
def order_food4(size: :large, quantity: 1, price: 4)
extra = :quantity == 1 ? :salad : :Burgers
cost = quantity * price
"#{quantity} #{size} #{extra}, coming right up! Thats is #{cost} dollar please"
end
- slower
+ method itself and use of it are more readable
Which one is better ? Depends on personal taste and the situation.
I use all of them and there is nothing in the design guides as far as I know that prefares one or the other.
In practice you will even combine some of them.
Parameters that are seldom changed are best given a default value and vice versa.
Methods that are called many times (eg recursive ones) could benefit from the faster and less memory consuming method 1.
In my opinion, readability is most important for a Ruby script, so if having a lot of parameters and feasable use method 3 or 4.
Some examples of use and benchmarks..
puts order_food1("large", 3, 4)
puts order_food2("large", 3, 4)
puts order_food3(size: "large", quantity: 3, price: 4)
puts order_food3
puts order_food4(size: "large", quantity: 3, price: 4)
puts order_food4
# 3 large Burgers, coming right up! Thats is 12 dollar please
# 3 large Burgers, coming right up! Thats is 12 dollar please
# 3 large Burgers, coming right up! Thats is 12 dollar please
# 1 large salad, coming right up! Thats is 4 dollar please
# 3 large Burgers, coming right up! Thats is 12 dollar please
# 1 large Burgers, coming right up! Thats is 4 dollar please
require 'benchmark'
Benchmark.bmbm do |x|
x.report("order_food1 ") { 10000.times { order_food1("large", 3, 12) }}
x.report("order_food2 ") { 10000.times { order_food2("large", 3, 12) }} # all parameters given
x.report("order_food2_def") { 10000.times { order_food2 }} # using default parameters
x.report("order_food3 ") { 10000.times { order_food3(size: "large", quantity: 3, price: 12) }} # all parameters given
x.report("order_food3 def") { 10000.times { order_food3 }} # using default parameters
x.report("order_food4 ") { 10000.times { order_food3(size: "large", quantity: 3, price: 12) }} # all parameters given
x.report("order_food4 def") { 10000.times { order_food3 }} # using default parameters
end
# user system total real
# order_food1 0.015000 0.000000 0.015000 ( 0.010420)
# order_food2 0.000000 0.000000 0.000000 ( 0.010675)
# order_food2_def 0.016000 0.000000 0.016000 ( 0.011007)
# order_food3 0.015000 0.000000 0.015000 ( 0.020182)
# order_food3 def 0.016000 0.000000 0.016000 ( 0.016954)
# order_food4 0.015000 0.000000 0.015000 ( 0.020256)
# order_food4 def 0.000000 0.000000 0.000000 ( 0.016968)