2009-01-20 24 views
6

मुझे ऑब्जेक्ट्स का एक पॉलिमॉर्फिक सरणी मिली है जो दो (अनौपचारिक) इंटरफेस को लागू करती है।मैं कैसे निर्धारित करूं कि कोई ऑब्जेक्ट पर्ल में एक विधि लागू करता है या नहीं?

if (hasattr(obj, 'some_method')) { 
    # `some_method` is only implemented by one interface. 
    # Now I can use the appropriate dispatch semantics. 
} else { 
    # This must be the other interface. 
    # Use the alternative dispatch semantics. 
} 

हो सकता है कि कुछ इस तरह काम करता है ?:

if (*ref(obj)::'some_method') { 
    # ... 

मैं कठिनाई बता जब वाक्य रचना और एक सबरूटीन आह्वान करने की कोशिश करेंगे है: मैं उन्हें की तर्ज पर प्रतिबिंब के साथ अंतर करने के लिए सक्षम होना चाहते हैं जब यह एक subroutine संदर्भ वापस करेगा। मैं पैकेज प्रतीक टेबल एटीएम से बहुत परिचित नहीं हूं और मैं बस कुछ हैक करने की कोशिश कर रहा हूं। :-)

अग्रिम धन्यवाद!

उत्तर

16
use Scalar::Util qw(blessed); 
if(blessed($obj) and $obj->can('some_method')){ 

} 

यहाँ एक विधि UNIVERSAL से सभी वर्गों द्वारा विरासत में मिली है "सकता है"। कक्षाएं इस विधि को ओवरराइड कर सकते हैं, लेकिन यह एक अच्छा विचार नहीं है।

इसके अलावा, समारोह के लिए एक संदर्भ रिटर्न "सकता है", तो आप कर सकते हैं:

$foo->can('some_method')->($foo , @args); 

या

my $sub = $foo->can('some_method'); 
$foo->$sub(@args); 

संपादित करें अपडेटेड चेन सिंटेक्स, ब्रायन फिलिप्स

+0

किसी भी तरीके से आरक्षित विधि नाम 'कर सकता है, या अगर आप इसे लागू करते हैं तो आप पैर में खुद को शूट करने के लिए बस होते हैं? – cdleary

+0

भूलें कि आपको ऑब्जेक्ट को स्पष्ट रूप से पास किए गए फ़ंक्शन संदर्भ में पास करने की आवश्यकता है: $ foo-> can ('some_method') -> ($ foo, @args)। वैकल्पिक रूप से, मेरा $ sub = $ foo-> कर सकता है ('some_method'); $ Foo -> $ उप (@args); –

+0

'कैन' ओवरराइड करने के खिलाफ एक सामान्य आदेश थोड़ा मजबूत है। ऐसा करने के अच्छे और महत्वपूर्ण कारण हैं। – darch

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

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