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?
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With