コンテンツへスキップ

オーバーロード

年齢を重ねる年数を示す数を受け取る become_older メソッドを定義できます。

class Person
  getter :age

  def initialize(@name : String, @age : Int = 0)
  end

  def become_older
    @age += 1
  end

  def become_older(years)
    @age += years
  end
end

john = Person.new "John"
john.age # => 0

john.become_older
john.age # => 1

john.become_older 5
john.age # => 6

つまり、同じ名前でパラメータの数や型が異なる複数のメソッドを持つことができ、それらは別のメソッドとして扱われます。これは *メソッドのオーバーロード* と呼ばれます。

メソッドはいくつかの基準でオーバーロードされます。

  • パラメータの数
  • パラメータに適用される型制約
  • 必須の名前付きパラメータの名前
  • メソッドが ブロック を受け入れるかどうか

例えば、4つの異なる become_older メソッドを定義できます。

class Person
  @age = 0

  # Increases age by one
  def become_older
    @age += 1
  end

  # Increases age by the given number of years
  def become_older(years : Int32)
    @age += years
  end

  # Increases age by the given number of years, as a String
  def become_older(years : String)
    @age += years.to_i
  end

  # Yields the current age of this person and increases
  # its age by the value returned by the block
  def become_older(&)
    @age += yield @age
  end
end

person = Person.new "John"

person.become_older
person.age # => 1

person.become_older 5
person.age # => 6

person.become_older "12"
person.age # => 18

person.become_older do |current_age|
  current_age < 20 ? 10 : 30
end
person.age # => 28

yield するメソッドの場合、コンパイラは yield 式があるためこれを把握していることに注意してください。これをより明示的にするには、末尾にダミーの &block パラメータを追加できます。

class Person
  @age = 0

  def become_older(&block)
    @age += yield @age
  end
end

生成されたドキュメントでは、ダミーの &block メソッドは、記述したかどうかに関わらず常に表示されます。

パラメータの数が同じ場合、コンパイラは制限の少ないものを最後にしてソートしようとします。

class Person
  @age = 0

  # First, this method is defined
  def become_older(age)
    @age += age
  end

  # Since "String" is more restrictive than no restriction
  # at all, the compiler puts this method before the previous
  # one when considering which overload matches.
  def become_older(age : String)
    @age += age.to_i
  end
end

person = Person.new "John"

# Invokes the first definition
person.become_older 20

# Invokes the second definition
person.become_older "12"

ただし、常に完全な順序があるとは限らないため、コンパイラは常に順序を把握できるとは限りません。そのため、制限の少ないメソッドは最後に配置する方が常に良いでしょう。