당신이 구축되면 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