どんなアクセスの方法monkeypatched法Perl?
-
05-09-2019 - |
質問
監督-選手コメン モンキーパッチ Perlクラス:を変更したい行動を既存の方法です。
このノードperlmonks 表示方法を示し 追加 る機能を既存のクラスです。さん、そしてこのパターンできるものを提供するために使用する新しい実装、既存の機能です。
しかし、そういったノウハウ、独自の機能です。
を探していて思ったこと。
use ExistingClass;
# TODO: Somehow rename existingFunction() to oldExistingFunction().
sub ExistingClass::existingFunction {
my $self = shift;
# New behavior goes here.
$self->oldExistingFunction(@_); # Call old behavior.
# More new behavior here.
}
解決
Typeglob課題
*ExistingClass::oldExistingFunction = *ExistingClass::existingFunction;
速や汚れています。このすべてのエイリアス existingFunction
記号を oldExistingFunction
.このサブんがしたことによるものでありまscalars、配列ハッシュ取り扱うという同じ名前です。
- メリット:な考え方でいいものです。"クイック"
- デメリット:"汚い"
Coderef課題
*ExistingClass::oldExistingFunction = \&ExistingClass::existingFunction;
# or something using *ExistingClass::symbol{CODE}
一つだけのエイリアスをいたしません。でないということになりますパッケージには赤、 oldExistingFunction
シンボルは世界的に見ればと考えている。最も適当な説明を選べ。
- メリット:そのエイリアシングしない'漏れを他の変数です。
- デメリット:以上を考え、文字を入力すく考える場合に*...{コード}構文(I personnallyで使用しない毎日)
語彙coderef
my $oldFunction = \&ExistingClass::existingFunction;
を使用 my
参照を保持の機能は、流動ブロック-ファイルです。そのために外部のコードを取得すのでご協力をお願す。心を呼び出し規約:
$self->$oldFunction(@args);
$oldFunction->($self, @args);
- メリット:無視界の課題な
- デメリット:硬く
ムース
見 jrockwayの回答.なってきて、適切な方法で、かありませんmuckingとglobおよび/または参照うがないわからないので十分に説明します。
他のヒント
あなたはムースのか<のhref = "HTTPを使用する必要があります.ORG / perldocの?クラス::メソッド::修飾子」のrel = "nofollowをnoreferrer">クラス::メソッド::モディファイするます。
その場合は、あなただけ言うことができます:
around 'some_method' => sub {
my ($orig, $self, @args) = @_;
# ... before original ...
$self->$orig(@_);
# ... after original ...
};
Memoize のこの良い例である。
ただ、レキシカル変数にコピーし、それを呼び出します。
my $existing_function_ref = \&ExistingClass::existingFunction;
*ExistingClass::existingFunction = sub {
my $self = shift;
$self->go_and_do_some_stuff();
my @returns = $existing_function_ref->( $self, @_ );
$self->do_some_stuff_with_returns( @returns );
return wantarray ? @returns : shift @returns;
};
あなたがOO-構文でそれについてよりよく感じる場合は、あなたがUNIVERSAL::apply
メソッドを作成することができます(または任意の基底クラスであなたが選びました)。
sub UNIVERSAL::apply {
my ( $self, $block ) = splice( @_, 0, 2 );
unshift @_, $self;
goto &$block;
}
あなたはこのようにそれをそのように呼び出すことができます:
my @returns = $self->apply( $existing_function_ref, @_ );
ムースのクラスについては、することができますだけの<のhref = "https://stackoverflow.com / / 40468" 分の576425> jrockway を言って何をすべきか。非ムースクラスについては、次の操作を行います。
use Class::MOP ();
use ExistingClass;
Class::MOP::Class->initialize('ExistingClass')->add_around_method_modifier(
existingFunction => sub {
my $orig = shift;
# new behaviour goes here
# call old behaviour
my $result = $orig->(@_);
# more new behaviour goes here
}
);
代替として、と間違って何ます:
package NewClass;
use base qw/ExistingClass/;
sub existingFunction {
# ....
}
sub oldExistingFunction {
my $self = shift;
return $self->SUPER::existingFunction(@_);
}