मैंने हाल ही में RailsConf 2014 की "ऑल द लिटिल थिंग्स" देखी। इस बातचीत के दौरान, सैंडी मेट्ज़ ने एक फ़ंक्शन का उल्लेख किया जिसमें एक बड़ा नेस्टेड-स्टेटमेंट शामिल है:
def tick
if @name != 'Aged Brie' && @name != 'Backstage passes to a TAFKAL80ETC concert'
if @quality > 0
if @name != 'Sulfuras, Hand of Ragnaros'
@quality -= 1
end
end
else
...
end
...
end
पहला कदम फ़ंक्शन को कई छोटे लोगों में तोड़ना है:
def tick
case name
when 'Aged Brie'
return brie_tick
...
end
end
def brie_tick
@days_remaining -= 1
return if quality >= 50
@quality += 1
@quality += 1 if @days_remaining <= 0
end
मुझे जो दिलचस्प लगा वह यह था कि इन छोटे कार्यों को लिखा गया था। brie_tick, उदाहरण के लिए, मूल tickफ़ंक्शन के संबंधित भागों को निकालकर नहीं लिखा गया था , लेकिन test_brie_*यूनिट परीक्षणों का उल्लेख करके खरोंच से । एक बार जब इन सभी यूनिट परीक्षणों को पारित कर दिया brie_tickगया , तो इस पर विचार किया गया। एक बार जब सभी छोटे कार्य किए गए थे, तो मूल अखंड tickफ़ंक्शन को हटा दिया गया था।
दुर्भाग्य से, प्रस्तुतकर्ता इस बात से अनजान था कि इस दृष्टिकोण के कारण चार में से तीन *_tickकार्य गलत हो रहे थे (और दूसरा खाली था!)। ऐसे किनारे मामले हैं जिनमें *_tickकार्यों का व्यवहार मूल tickकार्य से भिन्न होता है । उदाहरण के लिए, @days_remaining <= 0में brie_tickहोना चाहिए < 0- इसलिए brie_tickसही ढंग से काम नहीं करता है जब days_remaining == 1और कहा जाता है quality < 50।
यहाँ क्या गलत हो गया है? क्या यह परीक्षण की विफलता है - क्योंकि इन विशेष किनारों के मामलों के लिए कोई परीक्षण नहीं थे? या फिर से संपर्क करने में विफलता - क्योंकि कोड को खरोंच से फिर से लिखे जाने के बजाय चरण-दर-चरण बदलना चाहिए था?