3

10 年間の C++ から Ruby への移行を模索する中で、最も単純なことを達成する方法を次から次へと推測しています。以下の古典的な形状の派生例を考えると、これが「Ruby Way」であるかどうか疑問に思います。以下のコードに本質的な問題はないと信じていますが、Ruby の能力をフルに活用していないと感じています。

class Shape
  def initialize
  end
end

class TwoD < Shape
  def initialize
    super()
  end

  def area
     return 0.0
  end
end

class Square < TwoD
  def initialize( side )
    super()
    @side = side
  end

  def area
    return @side * @side
  end
end

def shapeArea( twod )
  puts twod.area
end

square = Square.new( 2 )

shapeArea( square ) # => 4

これは「The Ruby Way」で実装されていますか? そうでない場合、これをどのように実装しますか?

4

2 に答える 2

7

Ruby の優れた点は、実装されたメソッドのコントラクトを提供するためだけに継承を使用する必要がないことです。代わりに、次のようにすることもできます。

class Square
  def initialize(side)
    @side = side
  end

  def area
    @side * @side
  end
end

class Circle
  def initialize(radius)
    @radius = radius
  end

  def area
    @radius * @radius * 3.14159
  end
end

shapeArea(Square.new(2))
shapeArea(Circle.new(5))

これはダックタイピングと呼ばれる機能です。twod に area メソッドがある限り (Ruby の用語では、twod は area に応答すると言います)、問題はありません。

于 2009-07-03T02:05:14.113 に答える
2

最初の答えは「Ruby のやり方」ですが、C++ (高度に型付けされた) から Ruby (ダックタイピング) への変化を感じている場合は、より家にいるように感じることができます。

class TwoD < Shape
  ...
  def area
    # make this truly look pure-virtual
    raise NoMethodError, "Pure virtual function called"
  end
end

もちろん、あなたは ruby​​ に移行しているので、同じことを繰り返さないようにすることもできます:

class Module
  def pure_virtual(*syms)
    syms.each do |s|
      define_method(s) { raise NoMethodError, "Pure virtual function called: #{s}" }
    end
  end
end

class TwoD < Shape
  pure_virtual :area
  ...
end
于 2009-07-03T13:47:55.923 に答える