2010-09-12 14 views
42

मैंने विभिन्न ब्लॉग पोस्टों के माध्यम से पढ़ने की कोशिश की है जो alias_method_chain और इसका उपयोग करने के कारणों का उपयोग करने का प्रयास करते हैं और इसका उपयोग नहीं करते हैं।रेल पर रूबी: alias_method_chain, यह वास्तव में क्या करता है?

http://weblog.rubyonrails.org/2006/4/26/new-in-rails-module-alias_method_chain

और

http://yehudakatz.com/2009/03/06/alias_method_chain-in-models/

मैं अभी भी alias_method_chain के लिए किसी भी व्यावहारिक उपयोग नहीं दिख रहा है: विशेष रूप से, मैं करने के लिए ध्यान लिया। क्या कोई कुछ चीजों को समझाने में सक्षम होगा।

1 - क्या यह अभी भी बिल्कुल उपयोग किया जाता है?
2 - आप alias_method_chain का उपयोग कब करेंगे और क्यों?

उत्तर

90

1 - क्या यह अभी भी बिल्कुल उपयोग किया जाता है?

जाहिर है हाँ, alias_method_chain()still used in Rails (संस्करण 3.0.0) के रूप में है।

2 - जब आप alias_method_chain और क्यों प्रयोग करेंगे?

(नोट:। निम्नलिखित काफी हद तक पाओलो पेरोटा है, जो एक उत्कृष्ट पुस्तक है कि आप अपने हाथों पर मिलना चाहिए है द्वारा Metaprogramming Ruby में alias_method_chain() की चर्चा पर आधारित है)

के साथ शुरू करते हैं एक बुनियादी उदाहरण:

class Klass 
    def salute 
    puts "Aloha!" 
    end 
end 

Klass.new.salute # => Aloha! 

अब मान लें कि हम लॉगिंग व्यवहार के साथ Klass#salute() चारों ओर करना चाहते हैं।

class Klass 
    def salute_with_log 
    puts "Calling method..." 
    salute_without_log 
    puts "...Method called" 
    end 

    alias_method :salute_without_log, :salute 
    alias_method :salute, :salute_with_log 
end 

Klass.new.salute 
# Prints the following: 
# Calling method... 
# Aloha! 
# ...Method called 

हम एक नई विधि salute_with_log() बुलाया परिभाषित और salute() को यह एलियास: हम कि पेरोटा क्या कहता है एक उर्फ ​​आसपास कर सकते हैं। salute() पर कॉल करने के लिए उपयोग किया जाने वाला कोड अभी भी काम करता है, लेकिन यह नया लॉगिंग व्यवहार भी प्राप्त करता है।हम यह भी मूल salute() को एक उपनाम परिभाषित, इसलिए हम अभी भी प्रवेश के बिना सलाम कर सकते हैं:

Klass.new.salute_without_log # => Aloha! 

तो, salute() अब salute_without_log() कहा जाता है। अगर हम लॉगिंग करना चाहते हैं, तो हम salute_with_log() या salute() पर कॉल कर सकते हैं, जो एक ही विधि के उपनाम हैं। उलझन में? अच्छा!

पेरोटा के अनुसार, चारों ओर उर्फ ​​इस तरह की रेल में बहुत आम है: रेल का एक और उदाहरण पर

देखो एक समस्या अपने तरीके से सुलझाने। कुछ संस्करणों पहले रेल कोड निहित एक ही मुहावरे के कई उदाहरण: एक उर्फ ​​ के आसपास (155) एक पद्धति के लिए एक सुविधा जोड़ने के लिए इस्तेमाल किया गया था, और विधि के पुराने संस्करण को नाम दिया गया था method_without_feature() जैसे कुछ। के अलावा विधि नाम, जो प्रत्येक समय बदल गया, यह कोड था, यह हमेशा स्थान पर डुप्लिकेट किया गया था। अधिकांश भाषाओं में, आप उस तरह के नकल से बच नहीं सकते हैं। रूबी में, आप अपने पैटर्न पर कुछ मेटाप्रोग्रामिंग जादू छिड़का सकते हैं और इसे अपने विधि में निकाल सकते हैं ... और इस प्रकार alias_method_chain() पैदा हुआ था।

दूसरे शब्दों में, आप मूल विधि, foo(), और बढ़ाया विधि, foo_with_feature() प्रदान करते हैं और आप तीन तरीकों के साथ अंत: foo(), foo_with_feature(), और foo_without_feature()। पहले दो में सुविधा शामिल है, जबकि तीसरा नहीं है। इन उपनामों को चारों ओर डुप्लिकेट करने के बजाय, alias_method_chain() provided by ActiveSupport आपके लिए सभी अलियासिंग करता है।

+32

+1 "उलझन में? अच्छा कहने के लिए +1" – jperelli

+11

और छोटे जोड़े: इसलिए अब हम केवल '' 'alias_method_chain टाइप कर सकते हैं: foo,: feature''' और हमारे पास 3 विधियां होंगी:' '' foo''', '' foo_withoutfefeature ''' foo_without_feature '' 'जो' Yases Sulaiman * के रूप में ठीक से अलियाकृत हैं – freemanoid

+2

से पहले वर्णन करें "कोई भी पर्याप्त उन्नत तकनीक जादू से अलग नहीं है।" आर्थर सी क्लार्क –

4

मुझे यकीन नहीं है कि यह रेल 3 के साथ शैली से बाहर हो गया है या नहीं, लेकिन यह अभी भी पहले से संस्करणों में सक्रिय रूप से उपयोग किया जाता है।

आप उस पद्धति को कॉल करने वाले किसी भी स्थान को संशोधित किए बिना किसी विधि को (या उसके बाद) विधि से पहले कुछ कार्यक्षमता इंजेक्ट करने के लिए उपयोग करते हैं। इस उदाहरण देखें:

module SwitchableSmtp 
    module InstanceMethods 
    def deliver_with_switchable_smtp!(mail = @mail) 
     unless logger.nil? 
     logger.info "Switching SMTP server to: #{custom_smtp.inspect}" 
     end 
     ActionMailer::Base.smtp_settings = custom_smtp unless custom_smtp.nil? 
     deliver_without_switchable_smtp!(mail = @mail) 
    end 
    end 
    def self.included(receiver) 
    receiver.send :include, InstanceMethods 
    receiver.class_eval do 
     alias_method_chain :deliver!, :switchable_smtp 
    end 
    end 
end 

ActionMailer के अतिरिक्त deliver! की प्रत्येक कॉल पर SMTP सेटिंग से बाहर गमागमन अनुमति देने के लिए है कि। alias_method_chain पर कॉल करके आप एक विधि deliver_with_switchable_smtp! परिभाषित करने में सक्षम हैं जिसमें आप अपनी कस्टम सामग्री करते हैं, और जब आप पूरा कर लेंगे वहां से deliver_without_switchable_smtp! पर कॉल करें।

alias_method_chain उपनाम वर्ष deliver! अपने नए कस्टम विधि करने के लिए है, तो अपने अनुप्रयोग के बाकी भी deliver! पता नहीं है अब भी अपने कस्टम सामान करता है।

+0

चाहिए नहीं 'alias_method_chain: देने !,: देने !,: deliver_with_switchable_smtp'! 'Alias_method_chain हो switchable_smtp'? – Waseem

+0

नहीं यह सही है। – Waseem

2

क्या यह बिल्कुल उपयोग किया जाता है?

Seems so। रेल डेवलपर्स

के बीच यह एक आम प्रथा है जब आप alias_method_chain का उपयोग करेंगे और क्यों?

चेतावनी के बावजूद, अभी भी alias_method_chain मुख्य जब एक मौजूदा विधि के लिए कार्यक्षमता इंजेक्शन लगाने के लिए प्रयोग किया जाता रणनीति है, कम से कम रेल 2.x में था और कई लोगों को यह विस्तार के बाद आता है। रेल टिकटों में उनकी पोस्ट और टिप्पणियों से कहने के लिए येहुदा को रेल 3.0 से alias_method_chain को हटाना चाहिए। यह अभी भी कई एक्सटेंशन द्वारा उपयोग किया जाता है जो निष्पादन के कुछ बिंदुओं पर कस्टम व्यवहार जोड़ते हैं, जैसे कि लॉगर्स, त्रुटि संवाददाता, बेंचमार्किंग, डेटा इंजेक्शन इत्यादि।

आईएमओ, सबसे अच्छा विकल्प मॉड्यूल को शामिल करना है, इस प्रकार आपके पास प्रतिनिधिमंडल पर सजावट। (उदाहरण के लिए, this post में उदाहरण 4 का पालन करें)। यदि आप चाहें तो कक्षाओं के तरीकों को प्रदूषित किए बिना आप ऑब्जेक्ट को अलग-अलग बदल सकते हैं। इसका नकारात्मक पक्ष यह है कि आपके द्वारा इंजेक्ट किए जाने वाले प्रत्येक मॉड्यूल के लिए विधि लुकअप श्रृंखला बढ़ जाती है, लेकिन वैसे भी मॉड्यूल भी वैसे भी हैं।

बहुत ही रोचक सवाल है, इस पर एक नजर डालेंगे कि अन्य लोग इसके बारे में क्या सोचते हैं।

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