Calculating the Price of Fish: Default Parameters in Ruby

A short introduction to using default parameters in Ruby.

A short introduction to using default parameters in Ruby.

I’m intending this post to be a gentle introduction to default parameters in Ruby. I’ll cover constants, expressions, and method calls in this context, and hopefully show how their use can make your code a bit cleaner.

Let’s pretend that we’ve been asked to write some Ruby code to calculate the price of a fish, depending on its species, weight (in kg) and age (in years). We could start with a simple Ruby method:

def price_of_fish( species, weight, age )
  #some complicated price calculation
  return price

which could be called using:

my_price = price_of_fish( :haddock, 10, 3 )

(The actual details of the price calculation don’t concern us, so I’ve skipped them for brevity.)

Now let’s assume that if we don’t know the age of a fish, we perform the price calculation on the basis that the fish is one year old. We can do this with a default parameter:

def price_of_fish( species, weight, length, age = 1 )

which will allow to call our method with:

my_price = price_of_fish( :haddock, 10 )

(Note that we can still specify the age if we want to.)

Now, let’s assume that the age of a fish can, in a lot of cases be calculated by dividing its weight by 5, and if we don’t supply an explicit age, we want to use this method to obtain the age. We can do this by simply replacing our fixed default value with an expression:

def price_of_fish( species, weight, age = weight / 5 )

Going further, it’s likely that the default method for calculating the age of a fish depends on its species as well as its weight, so we can set up another method:

def default_age_of_fish( species, weight )
  #complicated calculation
  return age

and use this as the default value when calculating the price:

def price_of_fish( species,
                   age = default_age_of_fish( species, weight ) )

The alternative to this would be to default the age to a special fixed value, such as nil or zero, then check in the price_of_fish method for this special value, and call the default_age_of_fish method if this value has been passed in. I feel this approach to be slightly untidy, and it doesn’t explicitly separate the logic of the price calculation and the age calculation.

A word of warning about something that has caught me out in the past. Passing an explicit nil value for a parameter with a default value is not the same thing as not passing that parameter at all and relying on the default value. Using our example method above, calling

price_of_fish( :herring, 11 )

will use the default value for the age parameter, but

price_of_fish( :herring, 11, nil )

will ignore the default value and use nil instead

As always, I’d be interested to hear your views on the price of fish, and default parameters - why not leave a comment below?

Related Posts

Let's Work Together

We would love to hear from you so let's get in touch!