2010-03-12 6 views
6

रनटाइम पर मूस ऑब्जेक्ट की विधि को प्रतिस्थापित करना संभव है? (से जो Moose::Meta::Method inherits) Class::MOP::Method के स्रोत कोड को देख कर मैंने निष्कर्ष निकाला किरनटाइम पर मूस ऑब्जेक्ट की विधि को आप कैसे बदलते हैं?

$method->{body} = sub{ my stuff } 

करके मैं रनटाइम पर एक वस्तु की एक विधि को बदलने के लिए सक्षम होगा। मैं विधि का उपयोग कर

$object->meta->find_method_by_name(<method_name>); 

बहरहाल, यह काफी बाहर काम नहीं किया हो सकता है।

यह रन टाइम पर तरीकों को संशोधित करने के बोधगम्य है? और, मूस के साथ ऐसा करने का तरीका क्या है?

उत्तर

4

मूस या नहीं, कि एक अच्छा विचार की तरह ध्वनि नहीं करता है।

इसके बजाय, अपने वस्तु डिजाइन विधि के लिए एक्सेसर है। उदाहरण के लिए, frobnicator विधि प्राप्त करने और उसे आमंत्रित करने के लिए आपकी कक्षा के उपयोगकर्ता My::Frobnicator->frobnicator->() का उपयोग कर सकते हैं और इसे सेट करने के लिए My::Frobnicator->frobnicator(sub { }) का उपयोग कर सकते हैं।

+1

सीनान बहुत अच्छा विचार :) धन्यवाद – xxxxxxx

4

सिनान के विचार एक अच्छी शुरुआत है।

लेकिन एक थोड़ा अतिरिक्त ट्वीक के साथ, आप सिर्फ एक सामान्य विधि का उपयोग कर की तरह अपने विधि एक्सेसर का उपयोग कर बना सकते हैं।

#!/usr/bin/perl 
use strict; 
use warnings; 
use Carp; 

my $f = Frob->new; 

$f->frob(
    sub { 
     my $self = shift; 
     print "$self was frobbed\n"; 
     print Carp::longmess('frob') 
    } 
); 

print "\nCall frob as normal sub\n"; 
$f->frobit; 

print "\nGoto frob\n"; 
$f->goto_frob; 

BEGIN { 
    package Frob; 
    use Moose; 

    has 'frob' => (
     is => 'rw', 
     isa => 'CodeRef', 
    ); 

    sub frobit { 
     &{$_[0]->frob}; 
    } 
    sub goto_frob { 
     goto $_[0]->frob; 
    } 

} 

Frob में दो विधियां बहुत समान हैं।

  • frobit कोड रेफरी के आक्रमणकारी समेत सभी तर्कों को पास करता है।
  • goto_frob कोड रेफरी के आक्रमणकारी समेत सभी तर्कों को पास करता है, और कोड रेफरी के साथ goto_frob के स्टैक फ्रेम को प्रतिस्थापित करता है।

जो उपयोग करना है उस पर निर्भर करता है कि आप ढेर में क्या चाहते हैं।


, एक Class::MOP::Method वस्तु के शरीर भंडारण munging तो $method->{body} = sub { 'foo' } तरह के बारे में:

यह एक अच्छा विचार है जब आप OOP कर रहे हैं कैप्सूलीकरण उल्लंघन करने के लिए कभी नहीं है। खासकर जब आप मूस और क्लास :: एमओपी जैसे जटिल ऑब्जेक्ट सिस्टम के साथ काम नहीं कर रहे हैं। यह परेशानी के लिए पूछ रहा है। कभी-कभी, आप जो चाहते हैं उसे प्राप्त करने का कोई और तरीका नहीं है, लेकिन फिर भी, encapsulation का उल्लंघन अभी भी एक बुरा विचार है।

3

previously उल्लेख का उपयोग MooseX::SingletonMethod आप एक वस्तुओं विधि बदल सकते हैं।

उदाहरण के लिए:

{ 
    package Foo; 
    use MooseX::SingletonMethod; 
    sub foo { say 'bar' }; 
} 

my $bar = Foo->new; 
my $baz = Foo->new; 

# replace foo method just in $baz object 
$baz->add_singleton_method(foo => sub { say 'baz' }); 

$bar->foo;  # => bar 
$baz->foo;  # => baz 

भी देखें इस अतः What should I do with an object that should no longer be used in Perl? को जवाब है, जो पता चलता है कि यह कैसे मूस भूमिकाओं का उपयोग करके प्राप्त किया जा सकता।

/I3az/

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