2009-09-12 14 views
18

यदि आपके पास कोई विशेषता है जिसे किसी भी समय संशोधित करने की आवश्यकता है, तो क्या इस एक्सेस में किए गए $self की सामग्री के साथ स्वयं को एक्सेसर लिखने और सीधे चारों ओर मिलाने का एक छोटा सा तरीका है?मूस में, मैं किसी भी समय सेट किए जाने पर किसी विशेषता को कैसे संशोधित करूं?

package Foo; 
use Moose; 

has 'bar' => (
    isa => 'Str', 
    reader => 'get_bar', 
); 

sub set_bar { 
    my ($self, $bar) = @_; 
    $self->{bar} = "modified: $bar"; 
} 

मुझे trigger माना जाता है, लेकिन ऐसा लगता है कि यह एक ही दृष्टिकोण की आवश्यकता है।

$self में हैश संदर्भ के साथ सीधे काम कर रहा है Moose में खराब अभ्यास माना जाता है, या क्या मैं एक गैर-मुद्दे के बारे में चिंता कर रहा हूं?

उत्तर

8

मुझे यकीन है कि संशोधन की किस तरह आप की जरूरत नहीं कर रहा हूँ, लेकिन आप को प्राप्त करने के लिए आप क्या द्वारा की जरूरत है सक्षम हो सकता है टाइप जबरन का उपयोग करके:

package Foo; 
use Moose; 

use Moose::Util::TypeConstraints; 

subtype 'ModStr' 
    => as 'Str' 
    => where { /^modified: /}; 

coerce 'ModStr' 
    => from 'Str' 
    => via { "modified: $_" }; 

has 'bar' => ( 
    isa => 'ModStr', 
    is => 'rw', 
    coerce => 1, 
); 

यदि आप इस दृष्टिकोण का उपयोग करते हैं, तो सभी मान संशोधित नहीं किए जाएंगे। कुछ भी है कि एक ModStr के रूप में मान्यता गुजरता सीधे इस्तेमाल किया जाएगा:

my $f = Foo->new(); 
$f->bar('modified: bar'); # Set without modification 

यह कमजोरी ठीक हो सकता है या यह इस दृष्टिकोण से बेकार बना सकता है। सही परिस्थितियों में, यह भी एक फायदा हो सकता है।

6

मुझे लगता है कि हैश संदर्भ का उपयोग कर एक trigger इस तरह के भीतर ठीक है:

package Foo; 
use Moose; 

has 'bar' => ( 
    isa => 'Str', 
    is => 'rw', 
    trigger => sub { $_[0]->{bar} = "modified: $_[1]" }, 
); 

ट्रिगर भी जब बार आर्ग निर्माता के साथ पारित सक्रिय करता है। यह तब नहीं होगा यदि आप अपनी खुद की set_bar विधि या विधि संशोधक के साथ परिभाषित करते हैं।

पुन: हैश संदर्भ - आम तौर पर मुझे लगता है कि विशेषता सेटर्स/गेटर्स के साथ रहना सर्वोत्तम है (जब तक कि ऊपर ट्रिगर के साथ) कोई आसान विकल्प नहीं है।

बीटीडब्ल्यू आपको recent post about triggersnothingmuch दिलचस्प द्वारा मिल सकता है।

+0

मूस :: मैनुअल :: ट्रिगर्स पर विशेषताओं की जांच करें - http://search.cpan.org/~drolsky/Moose-0.88/lib/Moose/Manual/Attributes.pod#Triggers –

3

यदि हैश से निपटने से आपको चिंता हो रही है, तो आप एक वैकल्पिक लेखक निर्दिष्ट कर सकते हैं और फिर अपने स्वयं के उचित 'सार्वजनिक' लेखक के भीतर से इसका उपयोग कर सकते हैं।

package Foo; 
use Moose; 

has 'bar' => (
    isa => 'Str', 
    reader => 'get_bar', 
    writer => '_set_bar', 
); 

sub set_bar { 
    my $self = shift; 
    my @args = @_; 
    # play with args; 
    return $self->_set_bar(@args); 
} 

यह, या चलाता है, मुझे कब और कैसे आप तर्क से छेड़छाड़ किए जाने की जरूरत पर निर्भर करता है एक अच्छा दृष्टिकोण होने के रूप में हड़ताल करेंगे।

(अस्वीकरण: अपरीक्षित कोड स्मृति से लिखा है, परतदार बढ़त का उपयोग के साथ एक नेटबुक पर एसओ ब्राउज़ कर)

+0

यह एक अच्छा साफ है समाधान हालांकि यह रचनाकारों के साथ काम नहीं करेगा। – mikegrb

+0

@mikegrb: मुझे यकीन नहीं है कि आप कन्स्ट्रक्टर के साथ वास्तव में क्या करना चाहते हैं, लेकिन आप निर्दिष्ट कर सकते हैं कि 'init_arg' विशेषता संशोधक का उपयोग करके एक कन्स्ट्रक्टर के माध्यम से एक मान निर्दिष्ट किया गया है, और/या आप' बिल्डर्स 'में कुछ चेक कर सकते हैं विधि – Ether

9

आप विधि संशोधक 'आस-पास' का उपयोग कर सकते हैं। कुछ ऐसा:

has 'bar' => (
    isa => 'Str', 
    reader => 'get_bar', 
    writer => 'set_bar' 
); 

around 'set_bar' => sub { 
    my ($next, $self, $bar) = @_; 
    $self->$next("Modified: $bar"); 
}; 

और हाँ, हैश मानों के साथ सीधे काम करना बुरा अभ्यास माना जाता है।

इसके अलावा, कृपया यह न मानें कि मैंने जो विकल्प प्रस्तुत किया वह आवश्यक है। उपप्रकारों और जबरन का उपयोग करना अधिकांश समय सही समाधान होने वाला है - यदि आप किसी प्रकार के संदर्भ में अपने पैरामीटर के बारे में सोचते हैं जिसे संभवतया आपके आवेदन के दौरान पुन: उपयोग किया जा सकता है, तो यह बेहतर डिजाइन होगा कि मनमाने ढंग से संशोधनों की तरह 'आस-पास' का उपयोग करके किया गया। @daotoad से जवाब देखें।

+1

इस काम के लिए आपको विशेषता को परिभाषित करते समय एक लेखक को घोषित करने की आवश्यकता है। उदाहरण के लिए, 'bar' => (is => 'rw', isa => 'str', writer => 'set_bar') – draegtun

+0

पुन: हैश मान "खराब अभ्यास" है: ट्रिगर्स और उदाहरणों में यह ठीक है देखा (मूस मेलिंग सूची पर) इसकी पुष्टि करें। – draegtun

+0

draegtun: जब तक मूस ने इसे बदल दिया है, डिफ़ॉल्ट लेखक विशेषता नाम है। यदि आप लेखक को निर्दिष्ट नहीं करना चाहते हैं तो आप उस पर चारों ओर डाल सकते हैं। –

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

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