Sonntag, 29. März 2015

Create concise Ruby methods!

In the available Ruby method name space there are also method names, which are known from collection classes like Array or Hash. Since they are quite common it is easy to understand the intention of such methods, especially when used in a similar context.
For example a Person class dealing with a bunch of forenames:
class BankAccount
  attr_accessor :attributes
  def initialize attributes={}
    @attributes = attributes.assert_valid_keys :name, :amount
  end

  def add_money money
    @attributes[:amount] += money
  end

  def attribute attribute_name
    @attributes[attribute_name]
  end

  def attribute= attribute_name, value
    @attributes[attribute_name] = value
  end
end
and:
bank_account = BankAccount.new name: 'John', amount: 1000
bank_account.add_money 200
bank_account.attribute :amount
=> 1200
bank_account.attribute :amount, 2000
bank_account.attribute :amount
=> 2000
can be refactored to:
class BankAccount
  attr_accessor :attributes
  def initialize attributes={}
    @attributes = attributes.assert_valid_keys :name, :amount
  end

  def << money
    @attributes[:amount] += money
  end

  def [] attribute_name
    @attributes[attribute_name]
  end

  def []= attribute_name, value
    @attributes[attribute_name] = value
  end
end
Sending the messages is not only less typing but more important it is way more clear what happens:
bank_account = BankAccount.new name: 'John', amount: 1000
bank_account << 200
bank_account[:amount]
=> 1200
bank_account[:amount] = 2000
bank_account[:amount]
=> 2000

Supported by Ruby 2.1.1 and Ruby on Rails 4.1.8