liveBook · Manning

Pass-through change

As explained in The Well-Grounded Rubyist, Fourth Edition

A pass-through override is a method override that performs additional behavior and then invokes the original method, typically forwarding its arguments and relying on its return value.

Suppose every call to `String#reverse` should log a message, but reversing should still work as before. A pass-through override adds the logging and then calls the original method. Because that call is the override’s final expression, its result becomes the override’s return value. section 13.2.3

class String
  alias __old_reverse__ reverse
  def reverse
    $stderr.puts "Reversing a string!"
    __old_reverse__
  end
end
puts "David".reverse

The alias preserves the original `reverse` before the new definition replaces it. The override writes to STDERR, then calls the alias; `puts` prints the reversed string to STDOUT. section 13.2.3

An alias is one way to reach the original implementation; `alias_method` can create one too. An override can instead use `super` when the method lookup path provides the method it needs. Pass-through code normally forwards the call’s arguments and relies on the original method for its result, though it may deliberately transform an argument first. section 13.2.3

Adapting a comparison

An Active Support override of `DateTime#<=>` checks whether the other object responds to `to_datetime`. If so, it calls `super` with that representation; otherwise, it calls `super` without changing the argument. This layers support for comparisons involving `Time` and `TimeWithZone` onto the existing comparison method. section 13.2.3

Calling the original method does not, by itself, preserve the interface. An override of `Regexp#match` that substitutes `[]` for a failed match changes how conditionals behave. Likewise, forcing `String#gsub!` to return the string instead of `nil` when nothing changes breaks code that tests whether a substitution occurred. Check return-value behavior before treating a core-method override as pass-through. section 13.2.1 section 13.2.3

How The Well-Grounded Rubyist, Fourth Edition covers it

How deep it goes
Works through alias-based logging and super-based comparison, then distinguishes delegation from overrides that change return-value behavior.
Examples
Uses a logging `String#reverse` override and an Active Support `DateTime#<=>` override that converts comparable objects.
What it assumes
Assumes familiarity with Ruby classes and method calls while demonstrating how aliases and super reach an earlier implementation.
What you can do after
Apply it via Ruby aliases or super to add behavior while checking that an override preserves the intended return-value contract.
How it connects
Connects method overriding, aliasing, super, return values, and core-class modification.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Well-Grounded Rubyist, Fourth Edition. The section links point to the parts of the book it draws on.