Last Updated:

What is the use of duck typing in Python | Examples

One of the most commendable features of Ruby is its support for a technique known as duck typing. Despite its humorous name, Duck Typing allows Ruby developers to write compressed, clean, and readable code with minimal effort – all of what drew us to Ruby.

"What would the Dodgers Duck do?"

The basic premise of duck typing is simple. If an entity looks, walks, and quacks like a duck, it is fair for every sense and purpose to assume that it is dealing with a member of the species anas platyrhynchos. In practical Ruby terms, this means that you can try calling any method on any object, regardless of its class.

To demonstrate, here's a simple scenario: You're working with a system that tracks shipping manifests for each container on the ship. The data for each manifest is easily retrieved through the RESTful web service:

# Fields:
# * package_count: number of packages in manifest (integer)
# * mass:          total mass of all packages, in kilograms (BigDecimal)
class ShippingManifest
  attr_accessor :package_count, :mass
end

Each ShippingManifest Your task is to take a set of manifests (provided in array

"Are you saying that the monster Loch Ness lives in your hot tub?"

The problem looks simple enough, right? Perhaps we could break it down into nine or ten lines of code:

def summarise_manifests
  # Grab the latest set of Manifests (returns an Array)
  manifest_set = ShippingManifest.all

  # Initialize our counters
  total_package_count = 0
  total_mass          = BigDecimal("0")

  manifest_set.each do |m|
    total_package_count += m.package_count
    total_mass += m.mass
  end

  return [total_package_count, total_mass]
end

Easy, but verbose. You can reduce this method to a single line of code:

def summarise_manifests
  ShippingManifest.all.sum
end

How? Duck prints!

"The key to the skeleton, eh? Where did you get that?

Our one-line solution uses one of Ruby's most powerful features: the Enumerable EnumerableArrayHash module.

Specifically, we use the method defined in ActiveSupportsum, which is available in every Rails project. As the name suggests, it is used to calculate the sum of a set of features. This is done using an inject function that uses a block to reduce a set of objects to a single value. In the case of sum

This makes sense when we're talking about numbers: 1 + 1 = 2 It's also easy to see how it can be used to concatenate strings:

['foo', 'bar', 'baz'].sum # => 'foobarbaz'

But how does Ruby know how to add two instances of our ShippingManifest class

It's easy. We say it like.

"It's only part of who I am. I'm actually pretty complicated.

"Everything is an object" is one of Ruby's main mantras. The consequence of this is that (almost) every operator is actually a method call to an instance of an object, which gives us the ability to define our own implementation for that operator. This means that we can do this:

class ShippingManifest < ActiveResource::Base
  # Returns a new instance of ShippingManifest containing the
  # sum of both `mass` and `package_count`
  def +(other)
    self.dup.tap do |neu|
      neu.mass          = @mass + other.mass
      neu.package_count = @package_count + other.package_count
    end
  end
end

By adding a few simple lines of code, we added functionality that made a potential ShippingManifest

"And let me remind you guys once again that you are listening to the Truth or... Aaaaaaa

Implementing Custom Behavior for the + Operator There are other operators for which custom behavior is implemented: &*-<<. Even == Need to sort the recordset? Implement a comparison operator ( <=>Enumerable.

As always, some code examples for this post are available on our GitHub account – feel free to fork them out and experiment! To get started, try implementing the behavior for -<=>Enumerable.