2010-04-01 12 views
6

मैं वर्तमान में केवल पढ़ने के लिए एक विशेषता सेट करने के लिए एक ब्लॉक eval का उपयोग करता हूं। क्या ऐसा करने का कोई आसान तरीका है?क्या मूस विशेषता केवल पढ़ने के लिए परीक्षण करने का एक आसान तरीका है?

काम कर कोड से

उदाहरण:

#Test that sample_for is ready only 
eval { $snp_obj->sample_for('t/sample_manifest2.txt');}; 
like([email protected], qr/read-only/xms, "'sample_for' is read-only"); 



अद्यतन

धन्यवाद friedo को, ईथर, और रॉबर्ट पी उनके जवाब के लिए और ईथर, रॉबर्ट पी करने के लिए, और उनकी टिप्पणियों के लिए jrockway।

मुझे पसंद है कैसे ईथर के जवाब सुनिश्चित करता है कि $is_read_only केवल एक सही या गलत मूल्य (अर्थात लेकिन कभी एक coderef) एक ! के साथ negating कर रहा है। Double negation यह भी प्रदान करता है। इस प्रकार, आप का उपयोग is() फ़ंक्शन में कर सकते हैं, बिना कोडफ़्रफ़ को प्रिंट किए।

सबसे पूर्ण उत्तर के लिए रॉबर्ट पी का उत्तर नीचे देखें। हर कोई एक दूसरे के जवाब और टिप्पणियों पर बहुत मददगार और बनाया गया है। कुल मिलाकर, मुझे लगता है कि उसने मुझे सबसे ज्यादा मदद की है, इसलिए अब उसे स्वीकार किए गए उत्तर को चिह्नित किया गया है। फिर, ईथर, रॉबर्ट पी, फ्रेडेडो, और जॉकॉक के लिए धन्यवाद।



मामले में आप, सोच रहा हो सकता है के रूप में मैं पहली बार में किया था, यहाँ get_attribute और find_attribute_by_name (from Class::MOP::Class) के बीच अंतर के बारे में दस्तावेज़ है:

$metaclass->get_attribute($attribute_name) 

    This will return a Class::MOP::Attribute for the specified $attribute_name. If the 
    class does not have the specified attribute, it returns undef. 

    NOTE that get_attribute does not search superclasses, for that you need to use 
    find_attribute_by_name. 
+0

कि बेहतर 'ठीक रूप में लिखा जाएगा ($ snp_obj -> मेटा-> get_attribute ('sample_for') -> get_write_method(), "'sample_for' केवल पढ़ने के लिए है"); '- परीक्षण विफलता पर, 'है()' दूसरे तर्क को मुद्रित करता है (जो एक coderef होगा) .. उल्लेख नहीं है कि आपके पास पहला और दूसरा तर्क उलट है: 'है ($ है, $ अपेक्षित, $ test_name)'। – Ether

+0

यदि आपकी @attribute_names सरणी सावधानी से बनाई गई है, तो आपको ठीक होना चाहिए; लेकिन यदि विशेषता मौजूद नहीं है तो आप विस्फोट करेंगे :) –

+0

+1 सुपरक्लास – user1027562

उत्तर

5

तकनीकी रूप से, एक विशेषता को पढ़ने या लिखने की विधि की आवश्यकता नहीं होती है। अधिकांश उस समय के समय, लेकिन हमेशा नहीं। एक उदाहरण (कृपा jrockway's comment से चोरी) के नीचे है:

has foo => ( 
    isa => 'ArrayRef', 
    traits => ['Array'], 
    handles => { add_foo => 'push', get_foo => 'pop' } 
) 

यह विशेषता उपलब्ध नहीं होगा, लेकिन मानक पाठकों और लेखकों के लिए नहीं।

तो हर स्थिति है कि एक विशेषता is => 'RO' के रूप में परिभाषित किया गया है में परीक्षण करने के लिए, आप दोनों लिखने और पढ़ने के लिए विधि की जांच की जरूरत है।आप इस सबरूटीन के साथ यह कर सकता है:

# returns the read method if it exists, or undef otherwise. 
sub attribute_is_read_only { 
    my ($obj, $attribute_name) = @_; 
    my $attribute = $obj->meta->get_attribute($attribute_name); 

    return unless defined $attribute; 
    return (! $attribute->get_write_method() && $attribute->get_read_method()); 
} 

वैकल्पिक रूप से, आप पिछले return से पहले एक डबल निषेध जोड़ सकते हैं वापसी मान boolify रहे हैं:

return !! (! $attribute->get_write_method() && $attribute->get_read_method()); 
+1

मुझे पहला उदाहरण पसंद है;) – jrockway

5

Class::MOP::Attribute में दस्तावेज के रूप में:

my $attr = $this->meta->find_attribute_by_name($attr_name); 
my $is_read_only = ! $attr->get_write_method(); 

$attr->get_write_method() लेखक विधि प्राप्त करेंगे (या तो आप एक cr उत्सर्जित या जो उत्पन्न हुआ था), या अगर कोई नहीं है तो अनिश्चित।

+0

में विशेषता का पता लगाने के तरीके को ध्यान में रखते हुए धन्यवाद! यह जानकर कि यह 'अनफिन' लौटाता है, एक लाइन परीक्षण के लिए अनुमति देता है (मैंने इसे यहां पोस्ट करने का प्रयास किया, लेकिन यह बहुत सुंदर नहीं दिख रहा था)। –

+0

अच्छा, असल में ... यह परीक्षण करता है यदि उसके पास एक लेखन विधि है। हालांकि यह जांच नहीं करता है कि इसमें रीड विधि है या नहीं। यह तकनीकी रूप से, या तो नहीं है। यह बहुत उपयोगी विशेषता नहीं है अगर यह नहीं करता है, लेकिन आप इसे प्राप्त कर सकते हैं! –

+0

@Robert: हाँ, कड़ाई से बोलते हुए यह जांचता है कि विशेषता "लिखने योग्य नहीं है" (isa => 'rw' नहीं), जो "readonly" (isa => 'ro') जैसी बिल्कुल नहीं है। – Ether

3

आप वस्तु की metaclass से प्राप्त करने के लिए सक्षम होना चाहिए:

unless ($snp_obj->meta->get_attribute('sample_for')->get_write_method) { 
    # no write method, so it's read-only 
} 

अधिक के लिए Class::MOP::Attribute देखें।

+0

धन्यवाद! मुझे यही चाहिए। –

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