2011-01-30 15 views
5

रुबी में ऐसा करने का उचित तरीका क्या है?रूबी मुहावरे: विधि कॉल या अन्य डिफ़ॉल्ट

def callOrElse(obj, method, default) 
    if obj.respond_to?(method) 
    obj.__send__(method) 
    else 
    default 
    end 
end 
+0

क्या ईएएफपी (यानी यहां कोशिश करने के लिए प्रयास करें) रुबी समुदाय में गठबंधन नहीं किया गया है, जिस तरह से यह पाइथोनिस्टस है? –

+0

@ करल। मैं सभी रूबीस्ट के लिए बात नहीं कर रहा हूं, लेकिन कुछ ऐसा करने के लिए (कम से कम) चार पंक्तियां लिखना है जो आप एक में कर सकते हैं, निश्चित रूप से कई रूबी प्रोग्रामर के लिए परेशान है (हालांकि वे शायद पाइथन में कुछ भी नहीं मानेंगे)। – tokland

+0

इसके अलावा, यदि मैं ओपी के इरादे में एक __default__ व्यवहार शामिल करता हूं तो मैं यहां एक कोशिश/छोड़कर निर्माण का उपयोग नहीं करता। मेरी राय में, यदि दोनों तरीकों (यानी 'भेज' और 'डिफ़ॉल्ट') हो सकता है, तो इसे "अपवाद" क्यों बनाएं? – slhck

उत्तर

3

क्योंकि यह एक जवाब के रूप में पेश नहीं किया गया है:: इस मामले Ick पहले से ही एक अच्छा समाधान है im

result = obj.method rescue default 

@slhck साथ के रूप में, मैं शायद जब मुझे पता था कि वहाँ था इस का उपयोग नहीं होता एक उचित मौका है कि ओबीजे विधि का जवाब नहीं देगी, लेकिन यह एक विकल्प है।

+2

जितना सरल है, इसमें किसी भी अपवाद को छायांकन करने में बड़ी कमी है जो obj.method उठाता है, आपको नहीं पता होगा कि इसमें कोई विधि नहीं है या यह अभी विफल रहा है। जब भी संभव हो मैं व्यक्तिगत रूप से इनस्थल बचाता से बचता। – tokland

+0

-1 कारण @tokland का उल्लेख किया। आप वास्तव में इसे सामान्य रणनीति के रूप में उपयोग नहीं कर सकते हैं। – Jazzepi

2

मैं शायद के लिए

obj.respond_to?(method) ? obj.__send__(method) : default 
+0

यह बहुत साफ है, लेकिन अनिवार्य रूप से वही कार्यक्षमता है। मैंने सोचा कि ऐसा करने का एक बेहतर तरीका होगा। – dsg

+0

ठीक है, अगर आप वही _functionality_ नहीं चाहते हैं तो आप क्या चाहते हैं? :) जहां तक ​​मेरा संबंध है, इस निर्णय को बाईपास करने का कोई तरीका नहीं है। लेकिन शायद किसी के पास एक विचार है। – slhck

+0

मैं कुछ ऐसा करने की उम्मीद कर रहा था: 'x = obj.method || default'। – dsg

3

तो जाना चाहते हैं आप x = obj.method || default को कुछ इसी तरह करना चाहते हैं? रुबी अपने स्वयं के निचले स्तर के निर्माण के लिए एक आदर्श भाषा है:

class Object 
    def try_method(name, *args, &block) 
    self.respond_to?(name) ? self.send(name, *args, &block) : nil  
    end 
end 

p "Hello".try_method(:downcase) || "default" # "hello" 
p "hello".try_method(:not_existing) || "default" # "default" 

शायद आपको इस अप्रत्यक्ष कॉलिंग को प्रतीक के साथ पसंद नहीं है? कोई समस्या नहीं है, तो Ick के maybe शैली को देखो और एक प्रॉक्सी वस्तु का उपयोग करें (आप कार्यान्वयन पता लगा सकते हैं):

p "hello".maybe_has_method.not_existing || "default" # "default" 

साइड नोट: मैं कोई OOP विशेषज्ञ हूँ, लेकिन यह मेरी समझ है कि आप चाहे पता होना चाहिए जिस वस्तु को आप बुला रहे हैं वह वास्तव में ऐसी विधि है। या nil वह ऑब्जेक्ट है जिसे आप नियंत्रित करना चाहते हैं ताकि विधियां न भेजें? object_or_nil.maybe.method || default

+0

यह आम तौर पर एक अच्छा जवाब है, लेकिन ध्यान दें कि कार्यान्वयन के परिणामस्वरूप कोई भी मौजूदा विधि 'झूठी' या 'शून्य' को बदले में "डिफ़ॉल्ट" के बजाय उपयोग की जाएगी। – Phrogz

+0

@Phrogz: यह एक अच्छा मुद्दा है, लेकिन इस मामले में आपको डिफ़ॉल्ट मान की आवश्यकता नहीं है, बस "obj.maybe.enabled?" स्थिति लिखें। वैसे भी, आप हमेशा अपनी आवश्यकताओं के लिए शायद पैटर्न को ट्विक कर सकते हैं: "obj.maybe (: default => true) .active?", लेकिन "डिफ़ॉल्ट" को सामान्य मामलों को कवर करना चाहिए। – tokland