Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The shape inheritance example and "The Ruby way"

In my quest to transition from a decade of C++ to Ruby, I find myself second guessing how to accomplish the simplest things. Given the classic shape derivation example below, I'm wondering if this is "The Ruby Way". While I believe there's nothing inherently wrong with the code below, I'm left feeling that I'm not harnessing the full power of 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

Is this implemented "The Ruby Way"? If not, how would you have implemented this?

like image 273
nathan Avatar asked Nov 17 '25 00:11

nathan


2 Answers

The beautiful thing about Ruby is you don't have to use inheritance just to provide a contract of implemented methods. Instead, you could have done this:

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))

This is a feature known as duck typing. So long as twod has an area method (in Ruby parlance we'd say twod responds to area), you're good to go.

like image 182
Pesto Avatar answered Nov 19 '25 14:11

Pesto


The first answer is "the ruby way", but if you're feeling the change from C++ (highly-typed) to ruby (duck-typing) you can make it feel more like home:

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

Of course you're transitioning to ruby so you could also avoid repeating yourself:

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
like image 28
Greg Avatar answered Nov 19 '25 12:11

Greg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!