閱讀文章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
到底爲什麼元編程泄氣? – 2011-12-26 04:08:04
Ruby語言的設計方式,我敢肯定沒有任何類會在你的第一個「it」塊中傳遞規範,並在第二個「it」塊中通過測試,除非它非常怪異並且使用C擴展與一些解釋器掛鉤。第二塊是多餘的。 – 2011-12-26 07:33:37
我唯一不鼓勵MP的原因是我不喜歡它,雖然有點武斷。如果有一個不需要它的實用解決方案,我寧可不使用它。 – Chris 2011-12-26 10:11:06