Duck Typing with Ruby

yu-croco
3 min readJun 23, 2019

--

This is the summaries of Duck Typing in Practical Object-Oriented Design: An Agile Primer Using Ruby

Wthat’s Duck Typing?

According to wikipedia,

Duck typing in computer programming is an application of the duck test — “If it walks like a duck and it quacks like a duck, then it must be a duck” — to determine if an object can be used for a particular purpose. With normal typing, suitability is determined by an object’s type. In duck typing, an object’s suitability is determined by the presence of certain methods and properties, rather than the type of the object itself

Well, WTF…!?

In short, object knows how to handle the methods. So whatever it is, all you have to do is to give a method to the object.

Concrete Example

Let’s consider the detail with a Class that handles salary calculations.This class handles how to calculate employees’ salary with case . In this case, you have to add case logics when new employee type is added, so the method will grow easily and hard to maintain.

class Salary
def calc_salaries(employees)
employees.each do |employee|
case employee
# if employee is proper, use this logic
when Proper
employee.calc_insurance_fee(insurance)
# if employee is part-timer, use this logic
when PartTimer
employee.calc_tax_reduction(working_hour)
# if employee is outsourcing, use this logic
when Outsourcing
employee.calc_special_bonus(special_reward)
end
end
end
end

The method is already 10 lines. If someone who knew Sandi Metz’ Rules For Developers saw this logic, they maybe get pissed off. Of course I will get angry and re-write this logic by myself.

On the other hand,

Each employee object knows which Class it belongs to. So send it a method that calculate its own salary (In this case, let’s make calc_salary), instead of using case . And add calc_salary method to each employee Class.

class Salary
def calc_salaries(employees)
employees.each do |employee|
# you just call employee's calc_salary method
employee.calc_salary
end
end
end
class Proper
def calc_salary
# write specific logic
end
end
class PartTimer
def calc_salary
# write specific logic
end
end
class Outsourcing
def calc_salary
# write specific logic
end
end

Now calc_salaries method is just 3 lines and you do not need to add specific logic on the method when you have new employee types!

If you want to force each employee to have calc_salary method, you can write like this.

class Employee
def calc_salary
raise NotImplementedError.new("You must implement #{self.class}##{__method__}")
end
end
class Proper < Employee
def calc_salary
# write specific logic
end
end
class PartTimer < Employee
def calc_salary
# write specific logic
end
end
class Outsourcing < Employee
def calc_salary
# write specific logic
end
end

Using inheritance, you can force what to implement on each subclass.

The merit of Duck Typing

You can keep code simply, clearly and transparently.
You do not have to divide logic in a method by objects’ type, so it’s easy to add new classes, and less risk of getting degradations.

The demerit of Duck Typing

Basically there is no demerit. If I have to say something, you need to have a skill of OOP (but it is not a demerit at all!!!!)

How to find Duck Typing

If you divided logics by case, kind_of?, is_a? or responds_to, you may miss Ducky!?

--

--

yu-croco
yu-croco

No responses yet