100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Ruby

Duck Typing in Ruby

Explore Ruby's duck typing philosophy — objects are defined by the methods they respond to, not by their class — and how it shapes idiomatic, flexible Ruby code.

Advanced OOPIntermediate8 min readJul 9, 2026
Analogies

Duck Typing in Ruby

Duck typing takes its name from the saying: 'if it walks like a duck and quacks like a duck, it's a duck.' In Ruby, this means code cares about what an object can do — which methods it responds to — rather than what class it belongs to. Instead of writing if object.is_a?(Duck) before calling object.quack, idiomatic Ruby simply calls object.quack and trusts that any object passed in will respond appropriately, or lets a NoMethodError surface naturally if it doesn't. This is a direct consequence of Ruby being dynamically typed: method calls are resolved at runtime based on the object's actual behavior.

🏏

Cricket analogy: A captain doesn't check a fielder's jersey number before throwing them the ball at short cover; if the player can catch, they get the catch, just as Ruby calls object.quack and trusts it responds rather than checking object.is_a?(Duck).

Why duck typing over type checking

Explicit type checks with is_a? or kind_of? couple your code to specific classes, making it brittle and hard to extend. Duck typing decouples code from concrete types, so any object that implements the expected interface can be used interchangeably — this is what allows File, StringIO, and custom loggers to all work anywhere Ruby expects something 'IO-like,' as long as they implement methods like read or write.

🏏

Cricket analogy: A selector who only picks players from a fixed list of 'opening batsmen' misses out on an all-rounder who could open just as well; duck typing lets any IO-like object like File or StringIO step into the same role, as long as it can 'bat.'

ruby
class PdfReport
  def render
    'PDF bytes...'
  end
end

class CsvReport
  def render
    'col1,col2\nval1,val2'
  end
end

# No shared superclass or interface declaration needed.
# Any object that responds to #render works here.
def publish(report)
  puts report.render
end

publish(PdfReport.new)
publish(CsvReport.new)

Checking capability, not class

When you genuinely need to verify an object supports an operation before calling it — for example, in a library that accepts many kinds of input — the duck-typed idiom is respond_to?, not is_a?. This still asks 'can you do this?' rather than 'what are you?', preserving the flexibility duck typing is meant to provide.

🏏

Cricket analogy: Before trusting a substitute fielder to take a high catch under pressure, a captain might ask 'can you catch?' rather than checking their registration category, just as respond_to? asks whether an object can act, not what it is.

ruby
def serialize(data)
  if data.respond_to?(:to_h)
    data.to_h
  elsif data.respond_to?(:to_a)
    data.to_a
  else
    data.to_s
  end
end

Duck typing is closely related to structural typing in statically typed languages like TypeScript or Go, where an object satisfies an interface simply by implementing its methods, with no explicit 'implements' declaration required. Ruby takes this idea further by resolving it entirely at runtime, with no compile-time interface check at all.

Because Ruby performs no compile-time checking, a typo like object.quak instead of object.quack won't be caught until that line actually executes — potentially in production. This is why comprehensive test coverage (e.g. via RSpec) matters more in duck-typed code than in statically typed languages.

  • Duck typing means Ruby cares about what methods an object responds to, not its class.
  • Prefer calling a method directly, or checking respond_to?, over checking is_a?/kind_of?.
  • Duck typing enables polymorphism without shared superclasses or explicit interfaces.
  • It trades compile-time safety for flexibility, making thorough tests essential.
  • Many core Ruby and Rails APIs (e.g. anything 'IO-like' or 'Enumerable-like') rely on duck typing.
  • It parallels structural typing in languages like TypeScript and Go, but is fully dynamic in Ruby.

Practice what you learned

Was this page helpful?

Topics covered

#Ruby#RubyStudyNotes#Programming#DuckTypingInRuby#Duck#Typing#Over#Type#StudyNotes#SkillVeris