è¨èªçã«äºã ã¨ãã話ã§ã¯ãªãã¦ãè¤æ°äººã§éçºããã¨ãã«ããããããªã®ã§ï¼ã¨ãããããã£ãã®ã§ï¼
åçã«ããããå½ã¦ãã«ã¯
# gotoãããç BEGIN { use UNIVERSAL::require (); if ( Foo->require ) { my $orig = Foo->can('func'); no warnings qw(redefine); *Foo::func = sub { my ($foo) = @_; # shiftããªãæ¹ã楽ãªãã¨ãå¤ã # pre-process... goto &{$orig}; # post-processãå¿ è¦ãªå ´åã¯è¨äºã®æå¾ã§ }; } }
ã¨ããã®ãå®ç³ï¼Hook::LexWrap使ãã£ã¦ãã話ããããã©æ¬çã¨ã¯éãã®ã§å²æï¼ã ã¨æãã¾ããããããã©ãã§ãããã¨ãã話ã
ã¨ããCatalystControllerã§å¤ãªãããã°æãåºã¦ãã¦ãåçããããå¤ãã¦ãåºç¶ãã¦ãã¦å°ãããããã
調ã¹ã¦ã¿ãã¨ãä»ã®ã¢ã¸ã¥ã¼ã«ã§ãåãFoo::funcã«å¯¾ãã¦åçããããå½ã¦ã¦ãã¦ãããã¤ããããã°æãåºåãã¦ãã¨ãããªãã ã£ããã¤ã¾ããã©ãããããFoo::funcã ã¨æ°ä»ããã«æ´ã«ã©ãããã¦ããã¨ãããã¨ã ã
ãªã®ã§ãFoo::funcã使ç¨ãããç®æã§åçããããå½ã¦ãã®ã§ã¯ãªããMyAppã«ï¼ãããã¯MyApp::ContextãMyAppå ã§useãã¦ãããªã©ãã¦ãã¡ãã«ï¼æ¸ãã¦ãããuseã§ã¯1度ããèªã¿è¾¼ã¾ãªãã®ã§1ããã»ã¹å ã§åããããã2度å½ã¦ã¦ãã¾ãäºãç¡ããªãã¨ããããã
ãã¡ããã©ããã¦ãå±æçã«å½ã¦ããã®ã§ããã°ãã¡ããã¨local *Foo::funcã«ãã¦ããã°ãã¾ãåé¡ã¯ç¡ãã¨æããï¼ãããããªãã¨ã¯ã»ã¨ãã©ãªãã ãããNet::MSNã§ã¡ãã£ã¨ä½¿ã£ããã©ï¼
æå¾ã«ã¡ãã³ã£ã¨ã³ã¼ãã®èª¬æãã
- BEGINãããã¯ã§è¡ãã®ã¯ãFoo::funcã使ã£ã¦ããBarãuseããã¦ãå ´åãèãã¦ã®äºãBEGINã§ãããªãã¨ãBarããããã®å½ãã£ã¦ãªãFoo::funcã使ã£ã¦ãã¾ããããã
- ãã¡ããuse Barããåã«ããããå½ã¦ãªãã¨ãããªãããuseããé çªãæ°ã«ããªãããããªãã
- ã§ãããã¯é¢åãªã®ã§ãPERL5OPT=-MMyApp::Contextãã¡ããæ¹ãããã®ãããããªãã
- ãã¡ããuse Barããåã«ããããå½ã¦ãªãã¨ãããªãããuseããé çªãæ°ã«ããªãããããªãã
- *Foo::func{CODE}ãããªãã¦Foo->can('baz')ã使ã£ã¦ããã®ã¯ãfuncãFooã§ã¯ãªãå ç¥ã¯ã©ã¹ã§å®ç¾©ããã¦ã¦ãæ°ã«ããªãã¦æ¸ãããã
- $orig->(@_)ã®é¨åãwantarrayãè¦ã¦ãã®ã³ã³ããã¹ãã§æ»ãå¤ãåãã¦returnããªãã¨ã¡ããã¨åããªããã
ä¸ã®ã³ã¼ãã«ã¯ããã¾ã§æ¸ããªãã£ããã©ãä¸å¿æ¸ããâ
ããã§ãï¼å¤åèªã¿ééã£ã¦ããã ã¨æãã¾ãããèªåãåéã£ã¦ãå¯è½æ§ãããã¾ãã®ã§ä¸å¿æ¸ãã¦ããã¾ãï¼
goto &{$orig}ã®å ´åã¯ãæåã«æ¸ããã³ã¼ãã®éãï¼ããã¦id:tokuhiromãæ¸ããéãï¼wantarrayã¯è¦ãªãã¦è¯ãã®ã§ãã
以ä¸ã®ã³ã¼ãã¯post-processãè¡ãããã«goto &{$orig}ããã«$orig->(@_)ãã¦ããã®ã§ãwantarrayå¨ããæ示çã«å¦çãã¦ã¾ãã
# post-processãè¡ãããã«gotoããªããç BEGIN { use UNIVERSAL::require (); if ( Foo->require ) { my $orig = Foo->can('func'); no warnings qw(redefine); *Foo::func = sub { my ($foo) = @_; # shiftããªãæ¹ã楽ãªãã¨ãå¤ã # pre-process... my @r; if ( !defined wantarray ) { $orig->(@_); } elsif (wantarray) { @r = $orig->(@_); } else { $r[0] = $orig->(@_); } # post-process... return wantarray ? @r : $r[0]; }; } }
Foo::funcãwantarrayè¦ã¦ãã«ããã«ããã£ã¦ããã¨ãèããã¨ãvoidã³ã³ããã¹ããã©ããã調ã¹ãªãã¨ãããªãã