2009-07-03 2 views
3

C++의 10 년에서 Ruby 로의 전환을 위해 가장 단순한 작업을 수행하는 방법을 추측했습니다. 아래의 고전적인 형태 파생 예제를 감안할 때 이것이 "루비 웨이"인지 궁금합니다. 아래 코드에 본래 아무런 문제가 없다고 생각하지만 Ruby의 모든 기능을 활용하지 못하고 있다고 느낍니다.모양 상속 예제 및 "The Ruby way"

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 

"루비 웨이"가 구현 되었습니까? 그렇지 않은 경우 어떻게 구현 했습니까?

답변

7

루비에 대한 아름다운 점은 구현 된 메소드 계약을 제공하기 위해 상속을 사용할 필요가 없다는 것입니다. 대신 다음을 수행 할 수 있습니다.

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가 영역 메소드를 가지고있는 한 (루비 용어로 우리는 twod가 영역에 응답한다고 말하고 싶습니다), 여러분은 잘합니다.

2

첫 번째 대답은 "루비 방법"입니다,하지만 당신은 (오리 타이핑) 루비 (높은 입력) C++에서의 변화를 느끼고 있다면 당신은 더 집 같은 느낌 만들 수 있습니다

class TwoD < Shape 
    ... 
    def area 
    # make this truly look pure-virtual 
    raise NoMethodError, "Pure virtual function called" 
    end 
end 
당신은 루비로 전환하고 물론

그래서 당신은 또한 자신을 반복하지 않도록 수 :

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 
+0

나는 이런 것들을 싫어. 우선'def area ... '를 입력하지 마십시오. 이미 메소드 없음 오류가 발생합니다. 코멘트를 추가하면 서브 클래스가 제대로 구현할 수 있도록 '영역'이 수행해야하는 작업을 설명해야합니다. –