http://jeffkreeftmeijer.com/2011/method-chaining-and-lazy-evaluation-in-ruby/ 문서를 읽은 후 메서드 체인 및 지연 평가를위한 더 나은 솔루션을 찾기 시작했습니다.루비 챌린지 - 메서드 체인 및 지연 평가
아래 다섯 가지 사양으로 핵심 문제를 요약 한 것 같습니다. 누구나 다 통과 할 수 있니?
아무거나 : 서브 클래 싱, 위임, 메타 프로그래밍, 그러나 후자를 위해 낙담.
최소한으로 종속성을 유지하는 유리한 것 :
require 'rspec'
class Foo
# Epic code here
end
describe Foo do
it 'should return an array corresponding to the reverse of the method chain' do
# Why the reverse? So that we're forced to evaluate something
Foo.bar.baz.should == ['baz', 'bar']
Foo.baz.bar.should == ['bar', 'baz']
end
it 'should be able to chain a new method after initial evaluation' do
foobar = Foo.bar
foobar.baz.should == ['baz', 'bar']
foobaz = Foo.baz
foobaz.bar.should == ['bar', 'baz']
end
it 'should not mutate instance data on method calls' do
foobar = Foo.bar
foobar.baz
foobar.baz.should == ['baz', 'bar']
end
it 'should behave as an array as much as possible' do
Foo.bar.baz.map(&:upcase).should == ['BAZ', 'BAR']
Foo.baz.bar.join.should == 'barbaz'
Foo.bar.baz.inject do |acc, str|
acc << acc << str
end.should == 'bazbazbar'
# === There will be cake! ===
# Foo.ancestors.should include Array
# Foo.new.should == []
# Foo.new.methods.should_not include 'method_missing'
end
it "should be a general solution to the problem I'm hoping to solve" do
Foo.bar.baz.quux.rab.zab.xuuq.should == ['xuuq', 'zab', 'rab', 'quux', 'baz', 'bar']
Foo.xuuq.zab.rab.quux.baz.bar.should == ['bar', 'baz', 'quux', 'rab', 'zab', 'xuuq']
foobarbaz = Foo.bar.baz
foobarbazquux = foobarbaz.quux
foobarbazquuxxuuq = foobarbazquux.xuuq
foobarbazquuxzab = foobarbazquux.zab
foobarbaz.should == ['baz', 'bar']
foobarbazquux.should == ['quux', 'baz', 'bar']
foobarbazquuxxuuq.should == ['xuuq', 'quux', 'baz', 'bar']
foobarbazquuxzab.should == ['zab', 'quux', 'baz', 'bar']
end
end
왜 메타 프로그래밍 것을 낙담 할까? –
Ruby 언어가 설계된 방식으로, 첫 번째'it' 블록에 스펙을 전달할 클래스가없고 두 번째'it' 블록에서 테스트를 실패하는 클래스가 없다는 것을 확신합니다. 실제로는 정말 이상하고 C 일부 인터프리터 후크가있는 확장. 두 번째 블록은 중복됩니다. –
MP를 낙담시키는 유일한 이유는 다소 임의적 인 제한 임에도 불구하고 나는 그 팬이 아닙니다. 나는 그것을 필요로하지 않는 실용적인 해결책이 있다면 그것을 사용하지 않을 것입니다. – Chris