2011-10-04 3 views
1

나는 루비를 처음 사용하지만 반복적 인 방법이 많은 상황에 처해있다.Dynamic Method define_method 내에서 호출

class Foobar 
    def some_method 
    # 
    end 

    def some_method2 
    # 
    end 

    def some_calculation 
    # 
    end 

    [:some_method_test, :some_method2_test].each do |method| 
    define_method method do 
     return self.send(method.to_s.chomp "_test")/some_calculation 
    end 
    end 
end 

.to_s.comp--에 대한 내 질문이이 글을 쓰는 나의 목표를 달성하는 또 다른 방법이있다 : 내 코드를 건조하려고 시도에서 나는 다음과 같은 것을 함께했다?

답변

2

예, 원래 이름으로 시작할 수 있습니다.

[:some_method, :some_method2].each do |method| 
    define_method :"#{method}_test" do 
    return self.send(method)/some_calculation 
    end 
end 

이러한 유형의 메타 프로그래밍은 매우 많은 수의 간단한 방법을 사용하지 않는 한 대개 의미가 없습니다.

2

사소한 메소드의 수를 줄이려고 할 수 있습니다. 당신이 등, 대신 some_method2generic_method(2) 전화, some_method 대신 generic_method(1)를 호출 할 위치 어쩌면 당신은 generic_method(attribute_desired)some_method, some_method2, some_method3을 대체 할 수

때때로 당신이 테스트되고있는 코드에 대해 뭔가를 말할 수있는 테스트. 테스트가 매우 지루한 경우 테스트되는 코드가 너무 지루하고 중복이 너무 많다는 의미 일 수 있습니다.

1

그리고 여기가 또 다른 솔루션 :이 방법으로

class Foobar 
    # Non-test method definitions ... 

    %w(some_method some_method2).each do |mthd| 
    class_eval(<<-EOS, __FILE__, __LINE__ + 1) 
     def #{mthd}_test 
     #{mthd}/some_calculation 
     end 
    EOS 
    end 
end 

, 방법 자체가 조금 느립니다 정의,하지만 그들은 send 같은 더 반사 메소드를 호출하지 않기 때문에 그들은 훨씬 더 빨리 실행하고 스택 추적은 얕은있다 .

BTW, %w(foo bar)단어을 나타내고 ['foo', 'bar']을 생성합니다.

<<-EOS 
    blah blah 
    blah blah 
EOS 

은 여러 줄 (HERE 문서)을 분산시키는 문자열입니다.

class_eval은 현재 클래스 (클래스 Foobar)의 컨텍스트에서 문자열을 스크립트로 평가합니다. __FILE____LINE__ + 1은 스택 경로의 파일 경로 및 행 번호에 영향을줍니다.