카테고리 없음

[루비 온 레일] 동일한 인스턴스에 대한 여러 메소드-DRY

행복을전해요 2021. 2. 18. 00:20

당신이 구축되면 method1, method2등 그들이 인스턴스 자체를 사용하여 반환하도록 self, 당신은 체인 방식 인터페이스를 구축 할 수 있습니다. 예를 들면 :

class Foo
  def method1
      # do something
          self
            end
            
              def method2
                  # do something
                      self
                        end
                        
                          def method3
                              # do something
                                  self
                                    end
                                    
                                      # more methods...
                                      end
                                      
                                      @var = Foo.new
                                      
                                      @var.method1.method2.method3
                                      
                                      # or if this gets too long
                                      
                                      @var.method1
                                          .method2
                                              .method3
                                              
-------------------

DRY를 사용하면 코드를 유지 관리하고 읽기 쉽게 만들 수 있습니다. 나는 하지 않습니다 당신이 입력하거나 과시 코드 곡예 문자 수를 단축하는 데 사용한다고 생각합니다.

@Arup과 @ p11y의 솔루션은 컨텍스트 내에서 훌륭하지만 일반적으로 (클래스 나 메서드에 대해 알기 전에) 일반적으로

@var.method1
@var.method2
@var.method3

작성하는 것보다 더 읽기 쉽고 유지 관리하기 쉽습니다.

%i[method1 method2 method3].each(&@var.method(:send)) 

(이것을 이해하려면 고급 루비에 능통해야합니다)

또는

@var.method1
    .method2
        .method3
        

(다시 한번 사라지는 행위는 도움이되는 것보다 미래의 독자에게 더 혼란 스럽습니다)

6 개월 안에 누가 여러분의 코드를 읽을 것인지, 그가 무슨 일이 일어나고 있는지 이해하는 가장 명확한 방법이 무엇인지 항상 생각하십시오.

-------------------

다음과 같이하십시오.

%i[method1 method2 method3].each { |m| @var.send(m) }

더 짧게 만들고 싶다면 다음을 사용하십시오.

%i[method1 method2 method3].each(&@var.method(:send))
-------------------

원래 답변을 작성했을 때 질문의 마지막 문장을 놓쳤습니다.

Btw, Model.new더 간결한 코드를 생성하기 위해 블록을 호출 할 수 있습니까?

그리고이 질문에 대한 대답은 '예'입니다. 이 패턴은 루비의 여러 gem (예 :)에서 구현되는 빌더 패턴 tire입니다.

이 패턴은 initialize메서드가를 사용하여 생성 된 객체의 컨텍스트에서 실행되는 블록을 수신함을 나타냅니다 instance_eval. 블록이 매개 변수를 받으면 블록의 범위를 변경하는 대신 인스턴스 객체가 전달됩니다.

class Model
  def initialize(name, &block)
      @name = name
          block.arity < 1 ? instance_eval(&block) : block.call(self) if block_given?
            end
            
              def method1
                  # something
                    end
                      def method2
                          # something
                            end
                              def method3
                                  # something
                                    end
                                    end
                                    

그리고 그 사용법은 다음과 같습니다.

@var = Model.new('model') do
         method1
                  method2
                           method3
                                  end
                                  

또는 또는 :

@var = Model.new('model') do |m|
         m.method1
                  m.method2
                           m.method3
                                  end
                                  


출처
https://stackoverflow.com/questions/22079838