रेल में संरक्षित और निजी तरीके


81

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

संपादित करें : अब तक के जवाब के लिए धन्यवाद। मैं रूबी में संरक्षित और निजी की अवधारणा को समझता हूं, लेकिन मैं उस विशिष्ट तरीके के स्पष्टीकरण की तलाश कर रहा हूं, जिस तरह की दृश्यता का उपयोग रेल एप्लिकेशन के विभिन्न टुकड़ों (मॉडल, नियंत्रक, सहायक, परीक्षण) के संदर्भ में किया जाता है। । उदाहरण के लिए, सार्वजनिक नियंत्रक विधियाँ कार्य विधियाँ हैं, अनुप्रयोग नियंत्रक में संरक्षित विधियों का उपयोग "सहायक विधियों" के लिए किया जाता है, जिन्हें कई नियंत्रकों द्वारा एक्सेस करने की आवश्यकता होती है, आदि।

जवाबों:


106

मॉडल के लिए, यह विचार है कि सार्वजनिक तरीके वर्ग के सार्वजनिक इंटरफ़ेस हैं। सार्वजनिक तरीकों का उपयोग अन्य वस्तुओं द्वारा किया जाना है, जबकि संरक्षित / निजी तरीकों को बाहर से छिपाना है।

यह अन्य वस्तु-उन्मुख भाषाओं की तरह ही अभ्यास है।

के लिए नियंत्रकों और परीक्षण, बस के रूप में आप को खुश करते हैं। दोनों नियंत्रक और परीक्षण कक्षाएं केवल त्वरित हैं और फ्रेमवर्क द्वारा बुलाए जाते हैं ( हां, मुझे पता है कि आप सैद्धांतिक रूप से दृश्य से नियंत्रक प्राप्त कर सकते हैं, लेकिन यदि आप ऐसा करते हैं, तो कुछ भी अजीब है )। चूँकि कोई भी कभी भी उन चीजों को सीधे नहीं बनाएगा, इसलिए इसके खिलाफ "सुरक्षा" करने के लिए कुछ भी नहीं है।

परिशिष्ट / सुधार: नियंत्रकों के लिए, आपको संरक्षित निजी के रूप में "सहायक" विधियों को चिह्नित करना चाहिए , और केवल उन कार्यों को ही सार्वजनिक होना चाहिए। ढांचा कभी भी आने वाली HTTP कॉल को उन कार्यों / विधियों के लिए नहीं करेगा जो सार्वजनिक नहीं हैं, इसलिए आपके सहायक तरीकों को उस तरीके से संरक्षित किया जाना चाहिए।

सहायकों के लिए इससे कोई फर्क नहीं पड़ेगा अगर कोई विधि संरक्षित या निजी है, क्योंकि उन्हें हमेशा "सीधे" कहा जाता है।

आप उन सभी मामलों में संरक्षित सामान को चिह्नित कर सकते हैं यदि यह आपके लिए चीजों को समझने में आसान बनाता है, निश्चित रूप से।


" नियंत्रकों के लिए, आपको" सहायक "विधियों को संरक्षित के रूप में चिह्नित करना चाहिए, और केवल क्रियाएं स्वयं ही सार्वजनिक होनी चाहिए। " क्या आप नियंत्रकों में किसी भी निजी तरीके को नहीं करने की सलाह दे रहे हैं? या क्या मुझे सचमुच ऐसा नहीं पढ़ना चाहिए?
डेनिस

2
आजकल मैं केवल निजी का उपयोग करता हूं। संरक्षित और निजी का उपयोग अधिकांश स्थानों पर परस्पर रूप से किया जाता है; लेकिन संरक्षित एक अजीब व्यवहार लाता है जिसकी मुझे वास्तविक दुनिया में कभी आवश्यकता नहीं थी।
15

2
मैं केवल निजी के रूप में अच्छी तरह से उपयोग करते हैं। यह कुछ दिशानिर्देशों का भी पालन करता है, जैसे कि थॉटबोट की "नियंत्रक विधियों को परिभाषित करते समय संरक्षित के बजाय निजी का उपयोग करें।"
डेनिस

68

आप एक निजी पद्धति का उपयोग करते हैं यदि आप किसी और को नहींself चाहते हैं लेकिन एक विधि का उपयोग करते हैं। आप एक संरक्षित विधि का उपयोग करते हैं यदि आप कुछ चाहते हैं तो केवल self and is_a?(self)एस कॉल कर सकते हैं।

यदि आपके पास "वर्चुअल" आरंभीकरण विधि है तो संरक्षित का एक अच्छा उपयोग हो सकता है।

class Base
    def initialize()
        set_defaults()
        #other stuff
    end

    protected
    def set_defaults()
        # defaults for this type
        @foo = 7
        calculate_and_set_baz()
    end

    private
    def calculate_and_set_baz()
        @baz = "Something that only base classes have like a file handle or resource"
    end
end

class Derived < Base
    protected
    def set_defaults()
        @foo = 13
    end
end

@foo के अलग-अलग मूल्य होंगे। और व्युत्पन्न उदाहरणों में @baz नहीं होगा

अपडेट: जब से मैंने यह लिखा है, रूबी 2.0+ में कुछ चीजें बदल गई हैं। आरोन पैटरसन ने http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html पर एक उत्कृष्ट लेख लिखा है।


10
प्रेम तुमने कैसे कहा self and is_a?(self)। मैंने हमेशा बच्चों के कक्षाओं में उपलब्ध होने के रूप में संरक्षित तरीकों की व्याख्या की है।
टेट जॉनसन

16
यहाँ ध्यान दें! यह अन्य भाषाओं के लिए एक महत्वपूर्ण अंतर है: बाल कक्षाओं में निजी तरीके भी उपलब्ध हैं। निजी और संरक्षित में एकमात्र अंतर यह है कि आप "self.set_defaults" के साथ संरक्षित विधियों को कॉल कर सकते हैं, जबकि निजी तरीकों को केवल "set_defaults" कहा जा सकता है।
9

एक अच्छा जवाब, लेकिन इसमें रेल शब्द भी शामिल नहीं है जो कि सवाल का बिंदु है
ब्रायन ऐश

5
उनके प्रश्न के संपादित समय मोहर को नोटिस करें। भविष्य में मैं अपने उत्तरों को अपडेट करने के लिए एक निजी पद्धति को परिभाषित करूंगा क्योंकि वे अपने प्रश्न बदलते हैं :)
EnabrenTane

जैसा कि एवरेल ने कहा, यह स्पष्टीकरण माणिक पर लागू नहीं होता है। जहाँ बाल वर्गों में निजी विधियाँ भी दिखाई देती हैं।
मिगेल

10

संरक्षित और निजी के बीच का अंतर सूक्ष्म है। यदि कोई विधि संरक्षित है, तो इसे परिभाषित करने वाले वर्ग या उसके उपवर्गों के किसी भी उदाहरण द्वारा बुलाया जा सकता है। यदि कोई विधि निजी है, तो इसे केवल कॉलिंग ऑब्जेक्ट के संदर्भ में कहा जा सकता है --- किसी अन्य ऑब्जेक्ट इंस्टेंस के निजी तरीकों को सीधे एक्सेस करना संभव नहीं है, भले ही ऑब्जेक्ट कॉलर के समान वर्ग का हो। संरक्षित तरीकों के लिए, वे एक ही कक्षा (या बच्चों) की वस्तुओं से सुलभ हैं।

http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Classes#Declaring_Visibility


2
लिंक के लिए धन्यवाद। लेकिन मैं इस बारे में अधिक सोच रहा हूं कि ये विशेष रूप से रूबी ऑन रेल्स में कैसे काम करते हैं (सार्वजनिक नियंत्रक विधियों को कार्रवाई के तरीकों के रूप में माना जाता है, आवेदन नियंत्रक में संरक्षित विधियों का उपयोग अन्य नियंत्रकों आदि द्वारा किया जा सकता है)
jrdioko

3
अंतिम स्थिति में "अनुप्रयोग नियंत्रक में संरक्षित विधियों का उपयोग अन्य नियंत्रकों द्वारा किया जा सकता है" ऐसा इसलिए है क्योंकि अन्य नियंत्रक (आमतौर पर) ApplicationController से विरासत में मिलते हैं, इसलिए वे वास्तव में उन सभी तरीकों के स्वामी हैं। वे उन्हें application_controller से एक्सेस नहीं कर रहे हैं: यह कभी भी त्वरित नहीं होता है। यह विशुद्ध रूप से एक माता-पिता के रूप में इस्तेमाल किया जाता है।
मैक्स विलियम्स

3

जैसा कि विधियों पर लागू किया गया है, आपको कक्षा दृश्यता (सार्वजनिक / संरक्षित / निजी) के शब्दार्थ का एक अच्छा विचार है। मैं जो भी पेशकश कर सकता हूं वह एक त्वरित रूपरेखा है जिस तरह से मैं इसे अपने रेल एप्लिकेशन में लागू करता हूं।

मैं बेस एप्लिकेशन कंट्रोलर में संरक्षित विधियों को लागू करता हूं ताकि वे फ़िल्टर के माध्यम से किसी भी नियंत्रक द्वारा कॉल कर सकें (जैसे पहले_फिल्टर: method_foo)। इसी तरह से, मैं उन मॉडलों के लिए संरक्षित तरीकों को परिभाषित करता हूं जिन्हें मैं उन सभी में एक आधार मॉडल में उपयोग करना चाहता हूं जो वे सभी से प्राप्त करते हैं।


2

यद्यपि क्रियाओं को किसी नियंत्रक के सार्वजनिक तरीके होने की आवश्यकता होती है, लेकिन सभी सार्वजनिक तरीके आवश्यक कार्य नहीं होते हैं। hide_actionयदि आप कैच-ऑल रूट का उपयोग कर रहे हैं तो आप इसका उपयोग कर सकते हैं /:controller/:action/:idया यदि यह अक्षम है (रेल 3 में डिफ़ॉल्ट) तो केवल स्पष्ट मार्गों वाले तरीकों को ही बुलाया जाएगा।

यह उपयोगी हो सकता है यदि आप नियंत्रक उदाहरण को किसी अन्य लाइब्रेरी जैसे लिक्विड टेंप्लेट इंजन में पास कर रहे हैं क्योंकि आप अपने लिक्विड फिल्टर और टैग में भेजने के बजाय एक सार्वजनिक इंटरफ़ेस प्रदान कर सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.