2009-12-03 4 views
7

は、ここで私が達成したいものです。どのようにしてサブルーチンを再定義し、古いものも保持できますか?

sub first { 
    print "this is original first"; 
} 

*original_first = \&first; 

sub first { 
    print "this is first redefined"; 
} 

original_first(); # i expect this to print "this is original first" 
first() # i expect this to print "this is first redefined" 

私はfirstのシンボルを保存することで、私は後で(名前original_first下)オリジナルのサブルーチンを呼び出すこともできるようにすることができるだろうと思いましたfirstに電話をかけ、再定義してください。しかし、私がoriginal_firstと呼んでも、私は "これが最初に再定義されました"ということをまだ得ています。私はこの仕事をするために何をしなければなりませんか?

答えて

9

あなたが期待するように、これは動作するはずです:コピーを保存する前に起こっ&first終わりまでに

BEGIN { 
    *first = sub { ... } 
} 

ので、両方の割り当て:あなたのコード内

sub first { 
    print "this is original first"; 
} 

*original_first = \&first; 

*first = sub { 
    print "this is first redefined"; 
}; 
+0

「最初の」シンボルを再定義してコード部分のみに影響を与えることは可能ですか? – Geo

+5

タイプグロブにcoderef(サブ{...}で生成)を代入すると、glob内のCODEエントリが置き換えられます。グロブ内の他のデータ型は変更されません –

+4

特定のブロック内の関数のみを置き換えるには、 'local * first = sub {...};'を使うこともできます。 –

9

は、Perlはこれに類似したサブ宣言の両方を解釈しルーチンを呼び出す。修正は、実行時の割り当てに2番目の宣言をすることです:

sub first { 
    print "this is original first"; 
} 

*original_first = \&first; 

*first = sub {print "this is first redefined"}; 

original_first(); # prints "this is original first" 
first();   # prints "this is first redefined" 
+0

良い説明。ありがとう! – Geo

+0

あなたが記述する 'sub {}' - > 'BEGIN {* ...}'の動作には引用が必要です。 – Ether

+0

私はperlmodから以下の説明を推測しています:サブルーチンの定義(とそのことについての宣言)は、シンボルテーブルが占有するパッケージ内に必ずしも位置する必要はありません。サブルーチンの名前を明示的に修飾することによって、パッケージ外にサブルーチンを定義することができます。 1. package main; 2. Some_package :: foo {...} Some_packageで定義された#&foo これはコンパイル時の型グロブ割り当ての略語です。 1. BEGIN {* Some_package :: foo = sub {... }} –

1

はあなたのためにすべてのことを扱うことができるHook::LexWrapモジュールを参照してください。モジュールを使用したくない場合は、ソースを見てください。ソースの表示方法を正確に示しています。

関連する問題