2009-02-12 9 views
9

मैंने कभी भी अनावश्यक नहीं देखा है - या किसी और चीज जो आपको किसी विधि को परिभाषित करने की अनुमति देती है - किसी भी अन्य प्रोग्रामिंग भाषाओं में। रुबी में इसकी आवश्यकता क्यों है?undef - आप रूबी में एक विधि को अपरिभाषित क्यों करना चाहते हैं?

संपादित करें: मैं बहस नहीं कर रहा हूं कि इसमें कुछ भी गलत है। मैं रनटाइम पर विधियों को परिभाषित करने के उद्देश्य को समझ नहीं पा रहा हूं? इसका उद्देश्य क्या है? इसका उपयोग कैसे किया जा सकता है? मैंने कभी सी या जावा में ऐसा नहीं किया है।

उत्तर

18

रूबी में रिक्त वर्ग पैटर्न भी है जिसे undef कार्यक्षमता की आवश्यकता है।

विचार आपकी नई कक्षा से प्रत्येक विधि को पट्टी करना है ताकि आप जो भी कॉल कर सकें, #method_missing में समाप्त हो जाए। इस तरह आप एक वास्तविक प्रॉक्सी को कार्यान्वित कर सकते हैं जो सब कुछ के माध्यम से बस shuffles। इसके साथ सजावटी पैटर्न को कार्यान्वित करना कोड की लगभग दस पंक्तियां है, भले ही आपकी लक्षित कक्षा कितनी बड़ी हो।

यदि आप देखना चाहते हैं कि क्रिया में मुहावरे रूबी के मॉकिंग फ्रेमवर्क में से एक को देखते हैं, तो वे इसे बहुत उपयोग करते हैं। कुछ flexmock की तरह।

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

+0

पर परिभाषित किया गया है, मुझे आपका #attack उदाहरण पसंद है। धन्यवाद। –

2

रनटाइम पर विधियों, कक्षाओं और वस्तुओं को परिभाषित करना रूबी की एक बहुत अच्छी विशेषता है। यह आपको कक्षाओं का विस्तार करने की अनुमति देता है (याद रखें कि वे "खुले" हैं)। यदि आप रेल को देखते हैं, तो इसमें मॉडल में ऑब्जेक्ट खोजने के लिए #find विधि है लेकिन आप find_by_user का भी उपयोग कर सकते हैं; वह विधि मौजूद नहीं है (इसलिए #method_missing कहा जाता है) लेकिन रन-टाइम पर बनाया जाता है।

यदि आप या DSL बनाना चाहते हैं, तो #missing_method का उपयोग कर उपयोगी हो सकता है।

+1

वास्तव में #method_missing activercord द्वारा प्रयोग किया जाता है जब आप find_by_user फोन नहीं है। विधि को कक्षा init – LDomagala

0

आप रनटाइम (उर्फ मेटाप्रोग्रामिंग) पर परिभाषित विधियों के उदाहरणों के लिए सभी रेल देख सकते हैं। अपनी कक्षा परिभाषा में एक विधि को कॉल करके, यह उस वर्ग के सभी उदाहरणों के लिए विधियों का एक संपूर्ण समूह परिभाषित कर सकता है ...

1

रनटाइम पर परिभाषित विधियों से संबंधित मॉड्यूल को आवश्यकतानुसार शामिल करने की तकनीक है। मैं एक रेल एप्लिकेशन पर काम करता हूं जहां हमें कभी-कभी विभिन्न प्रारूपों में डेटा निर्यात करना पड़ता है। समय के 99%, फार्म वस्तु निर्यात से संबंधित तरीकों की जरूरत नहीं है, लेकिन हमारे निर्यात रैक काम में, हम जैसे कुछ कार्य करें:

Form.send(:include, FormExportingMethods) 

तो यह केवल उन तरीकों है जब यह उन्हें जरूरत है।

इस तरह की गतिशीलता रूबी के बारे में मुझे पसंद है। जबकि कुछ भाषाओं में, आपको अपनी कक्षाओं और वस्तुओं को सामने रखना होगा, रूबी आपको कहने देता है "ओह, मुझे अपने सुअर को अभी पंख रखने की ज़रूरत है? मैं उन्हें बस संलग्न करूंगा।"

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

0

यदि आप एक ओआरएम के साथ सिंगल टेबल विरासत का उपयोग करते हैं, जैसे ActiveRecord, तो आप उन फ़ील्ड के तरीकों को अपरिभाषित करना चाहते हैं जिनका उपयोग किसी विशेष वर्ग/ऑब्जेक्ट के लिए नहीं किया जा रहा है।

# table: shapes, with columns: name, sides, radius, type 
class Shape < ActiveRecord::Base 
end 

class Circle < Shape 
end 

class Square < Shape 
    undefine_method :radius 
end 

नोट: यह वास्तव में ActiveRecord में काम नहीं करता के रूप में यह आंतरिक रूप से एक विधि की उम्मीद के लिए हर क्षेत्र हमेशा से परिभाषित करने की।

नोट: एक वर्ग में त्रिज्या होता है जिसका उपयोग आमतौर पर नहीं किया जाता है, लेकिन आपको गिस्ट मिलता है? किसी सर्कल के डेटाबेस में संग्रहीत कुछ संपत्ति के बारे में सोचें, लेकिन स्क्वायर नहीं है।

0

मैं बाहरी एपीआई का उपभोग कर रहा हूं, और JSON प्रतिक्रियाओं में से एक में "विधियों" नामक एक फ़ील्ड है। मैं जेसन को और अधिक प्रबंधनीय बनाने के लिए, जेसन के चारों ओर एक ओपनस्ट्रक्चर बना रहा हूं। OpenStruct.methods को कॉल करते समय, यह ऑब्जेक्ट इंस्टेंस विधि "विधियों" का परिणाम देता है।

तो मैंने किया:

class MyOpenStruct < OpenStruct 
    def methods 
    end 

    undef :methods 
end 

openStruct = OpenStruct.new(my_json) 
0

मैं इस mixins साथ संयोजन के रूप में प्रयोग किया जाता देखा है; इसलिए आप पूरी चीज को शामिल कर सकते हैं और फिर उन विधियों को अनदेखा कर सकते हैं जिन्हें समर्थन नहीं देना चाहिए .. उदा। रूबी ग्राफिक्स लाइब्रेरी shoes

button वर्ग clickable मॉड्यूल में घुलमिल, और फिर undef के release विधि क्योंकि बटन इसका समर्थन नहीं करते।

एक और त्वरित उदाहरण है, इसलिए इसे यहाँ उपलब्ध है:

module Walkable 
    attr_accessor :location 
    def walk(steps) 
    @location += steps 
    end 
    def walk_back(steps) 
    @location -= steps 
    end 
end 
class Zombie 
    include Walkable 
    undef walk_back #zombies can only walk forwards 
end 
संबंधित मुद्दे