2012-03-15 13 views
6

मेरे पास दो उदाहरण हैं जो एक ही परिणाम देते हैं।जब ब्लॉक फ़ंक्शन (रूबी) से अधिक उपयोगी होते हैं?

ब्लॉक के साथ

:

def self.do_something(object_id) 
    self.with_params(object_id) do |params| 
    some_stuff(params) 
    end 
end 

def self.with_params(object_id, &block) 
    find_object_by_id 
    calculate_params_hash 
    block.call(params_hash) 
end 

और विधि के साथ:

def self.do_something(object_id) 
    some_stuff(self.get_params(object_id)) 
end 

def self.get_params(object_id) 
    find_object_by_id 
    calculate_params_hash 
    params_hash 
end 

दूसरा समाधान और अधिक सरल लगता है, लेकिन मुझे लगता है हमारे आवेदन कोड में पहले एक के कुछ प्रयोगों में पाया गया। मेरा सवाल है: किस स्थिति में पहली बार सिफारिश की जाती है? प्रत्येक के पेशेवरों और विपक्ष क्या हैं?

+0

आपके उदाहरण में मुझे विश्वास नहीं है कि प्रो ऑब्जेक्ट का उपयोग करने का कोई कारण है। प्रो ऑब्जेक्ट्स का पूरा बिंदु उन्हें लेक्सिकल वातावरण में बना रहा है और उन्हें तर्क के रूप में अन्य कार्यों में भेजना है। –

+0

टैग के रूप में "proc" जोड़ा गया। –

+0

'some_stuff (पैराम्स) क्या करता है, क्या यह कुछ देता है? – nkm

उत्तर

2

अपने उदाहरण के अनुसार एक ब्लॉक और समारोह के बीच मुख्य अंतर यह है कि ब्लॉक बुला समारोह के संदर्भ में चलाता है।

def self.do_something(object_id) 
    x = "boogy on" 
    self.with_params(object_id) do |params| 
    some_stuff(params) 
    puts x 
    end 
end 

ब्लॉक के भीतर कोड चर x है कि ब्लॉक के बाहर परिभाषित किया गया था पहुँच सकते हैं:

इसलिए यदि आपके उदाहरण के रूप में किया गया था। इसे बंद करना कहा जाता है। अगर आप अपने दूसरे उदाहरण के अनुसार सिर्फ एक समारोह बुला रहे थे तो आप ऐसा नहीं कर पाए।

ब्लॉक के बारे में एक और दिलचस्प बात यह है कि वे बाहरी कार्य के नियंत्रण प्रवाह को प्रभावित कर सकते हैं।तो यह करना संभव है:

def self.do_something(object_id) 
    self.with_params(object_id) do |params| 
    if some_stuff(params) 
     return 
    end 
    end 

    # This wont get printed if some_stuff returns true. 
    puts "porkleworkle" 
end 

यदि ब्लॉक के भीतर कुछ_स्टफ कॉल एक वास्तविक मूल्य देता है, तो ब्लॉक वापस आ जाएगा। यह ब्लॉक से बाहर हो जाएगा और की डोसॉमिंग विधि से बाहर हो जाएगा। porkleworkle आउटपुट नहीं मिलेगा।

अपने उदाहरणों में आप इनमें से किसी पर भरोसा नहीं करते हैं, इसलिए फ़ंक्शन कॉल का उपयोग शायद अधिक क्लीनर है।

हालांकि, ऐसी कई स्थितियां हैं जहां इन चीजों का लाभ लेने की अनुमति देने के लिए ब्लॉक का उपयोग करना अमूल्य है।

3

आम तौर पर लोग कोड का एक और टुकड़ा के अंदर कोड का एक टुकड़ा चलाने के लिए ब्लॉक का उपयोग करते हैं। उदाहरण:

DB.with_shard_for_user(user_id) do |db| 
    # perform operations on a user's shard 

end # shard is reverted back to original value 

File.new(filename) do |file| 
    # work with file 
end # file is closed automatically 

User.transaction do 
    # run some operations as a single transaction 
end 

इन ब्लॉक्स उनके शाब्दिक संदर्भ पर बंद हो जाती हैं (वे जहां ब्लॉक घोषित किया जाता है से चर पर कब्जा है, और उन्हें जगह में ले जब ब्लॉक कहा जाता है)।

एक ब्लॉक को स्वीकार करने वाली विधि की योजनाबद्ध संरचना।

def transaction 
    open_transaction # pre- part 

    yield if block_given? # run provided code 

    commit_transaction # post- part 
rescue 
    rollback_transaction # handle problems 
end 

आपके पहले उदाहरण में, ब्लॉक का उपयोग शायद अनुचित (IMHO) है। कोई स्पष्ट कारण के लिए बहुत जटिल है।

1

जब आप with_params() के साथ कॉल करते हैं, तो आप केवल डेटा में नहीं भेज रहे हैं, आप चलाने के लिए कुछ कोड भी प्रदान कर रहे हैं। यदि विभिन्न ब्लॉकों with_params में भेजा जाता है देखें() फोन:

... 
self.with_params(object_id) do |params| 
    some_other_stuff() 
    some_stuff(params) 
end 
... 

और कहीं और:

... 
self.with_params(object_id) do |params| 
    even_more_stuff(params) 
end 
... 

ब्लॉक सभी एक ही या with_params() सिर्फ एक जगह से कहा जाता है कर रहे हैं तो आप ब्लॉक को खत्म करने पर विचार कर सकते हैं।

समेकित करने के लिए: यदि आप कोड (ब्लॉक) के साथ-साथ डेटा के विभिन्न बिट्स को विधि में पास करना चाहते हैं तो ब्लॉक का उपयोग करें: हे with_params, इस डेटा (object_id) को ले जाएं और, वैसे, इस कोड को चलाएं (ब्लॉक) जबकि आप इसमें हैं।

BTW आप दो उदाहरण में अलग अलग बातें कर रहे हैं: with_params() रिटर्न

some_stuff(params_hash) 

ब्लॉक मूल्यांकन करने के बाद। और get_params() सिर्फ रिटर्न

params_hash 
1

एक ब्लॉक पूरी तरह से आपके कोड पर भरोसा करता है, लेकिन एक फ़ंक्शन का अपना कोड होता है।

तो, यदि आपका कोड स्थिति से स्थिति बदलता है, तो ब्लॉक का उपयोग करें। यदि नहीं, तो एक फ़ंक्शन बनाएं और इसे ब्लॉक बॉक्स के रूप में उपयोग करें।

संबंधित मुद्दे