Sonntag, 27. April 2014

Return something meaningful! ... Ruby methods.

The response of a message should always be appropriate. And that means if a method promises to do something meaningful, its response should be accordingly.
For example:
class Person
  attr_accessor :born_at
  def adult?
    unless born_at.nil?
      (born_at.year - Date.current.year) > 18
    end
  end
end
and trying it in IRB:
Person.new.adult?
=> nil
Well, since a nil object behaves like a false object in a condition, it works in most cases as expected. But apart from potentially breaking codes relying on that response, it is breaking the promise to return a meaningful result (either true or false) That nasty response behaviour can be refactored to:
class Person
  attr_accessor :born_at
  def adult?
    return false if born_at.nil?
    (born_at.year - Date.current.year) > 18
  end
end
So nil oftentimes is not a appropriate response.
Meaningful responses not only refer to getter methods, but also to setter methods.
The example:
class Stack
  def initialize
    @store = Array.new
  end

  def push element
    @store << element
  end

  def size
    @store.size
  end
end
in IRB again:
stack = Stack.new
stack.push 42
=> [42]
Why should the setter method push return an array, which is an internal data structure? That is not meaningful. More useful is to return self instead:
class Stack
  def initialize
    @store = Array.new
  end

  def push element
    @store << element
    self
  end

  def size
    @store.size
  end
end
so that the result does not reveal internal and dull data structures. Instead the result can be used for chaining (read Chain your Ruby methods!), like:
stack = Stack.new
stack.push(42).size
=> 1
Think about the result of EVERY method.

Supported by Ruby 1.9.3