22

私はこのコードを持っています:

def setVelocity (x, y, yaw)
  setVelocity (Command2d.new(x,y,yaw))
end
def setVelocity (vel)
......
end 

vel は、3 つの属性を持つ Command2D クラスであり、Comparable で + を定義します。基本的には、これら 3 つの属性を管理するのに便利なクラスなので、ライブラリ内で内部的に使用したいと考えています (それらを非公開にしたり、与えたりしたくありません変な名前)。ただRubyはパラメータ数が違っても最後のsetVelocityしか保持していないようです。そのため、3 つのパラメーターを指定して setVelocity を呼び出すと、そのメソッドを 1 つのパラメーターだけで呼び出す必要があることがわかります。

4

3 に答える 3

40

Ruby は実際にはオーバーロードをサポートしていません。

このページには、詳細と回避策が記載されています。基本的に、可変数のパラメーターを持つ単一のメソッドを作成し、それらを適切に処理します。

(個人的には、2 つの異なる「偽のオーバーロード」を認識するメソッドを 1 つ作成し、各オーバーロードに対して 1 つのメソッドを作成し、異なるパラメーターを反映する異なる名前を付けることをお勧めします。)

または、最初に別の名前を指定するだけです:)

于 2009-07-10T09:31:40.753 に答える
2

比較のために、これを解決する方法を次に示します。

#!/usr/bin/env ruby

class Command2D
  def initialize(x, y, yaw)
    @command = [x, y, yaw]
  end
end

class Vehicle
  def velocity=(command_or_array)
    case command_or_array
    when Command2D
      self.velocity_from_command = command_or_array
    when Array
      self.velocity_from_array = command_or_array
    else
      raise TypeError, 'Velocity can only be a Command2D or an Array of [x, y, yaw]'
    end
  end

  private

  def velocity_from_command=(command)
    @velocity = command
  end

  def velocity_from_array=(ary)
    raise TypeError, 'Velocity must be an Array of [x, y, yaw]' unless ary.length == 3
    @velocity = Command2D.new(*ary)
  end
end

v1 = Vehicle.new
v1.velocity = Command2D.new(1, 2, 3)

v2 = Vehicle.new
v2.velocity = [1, 2, 3]

p v1
p v2
于 2009-07-10T12:29:18.173 に答える
0

attr_accessorを使用して属性を追加すると、getter と setter が自動的に取得されます。または、 attr_readerまたはattr_writerを使用して、読み取り専用または書き込み専用の属性を取得します。

class Foo
  attr_accessor :velocity
end

この属性の値を次のように設定および取得できるようになりました。

foo = Foo.new
foo.velocity = 100
puts foo.velocity  # => 100

いくつかのパラメーターに基づいて属性を設定するメソッドを追加する場合は、予想される入力の種類を反映した名前を使用します。

def velocity_from_yaw(x, y, yaw)
  velocity = Command2d.new(x, y, yaw)
end

この場合、おそらくもっと良い名前を見つけることができますが、 xy、およびyawがコンテキストで実際に何を意味するのかわかりません。

于 2009-07-10T09:59:05.440 に答える