• ベストアンサー

オーバーライドについて

perlの出力結果を加工するため、ラクダ本を読んでprint関数のオーバーライドに挑戦したのですが、 どうしてもうまくいきません。 BEGIN { *CORE::GLOBAL::print = sub{ 1 }; }; print 2; の様にやっても、2が出力されてしまいます。 他の関数ではこの方法で動くようでした。 printはオーバーライドできないのでしょうか。 マニアックな質問かもしれませんが、よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

v5.8.1の時点でオーバーライドできないものに defined,delete,do,else,elsif,eval,exists,for,foreach,format,glog,goto,grep,if,last,local,m,map,my,next,no,our,package,pos,print,printf,prototype,q,qq,qr,qw,qx,redo,require,return,s,scalar,sort,split,study,sub,tie,tied,tr,undef,unless,untie,until,use,while,y があります。その他のものはオーバーライドできます。(クックブック12.12(日本版2版P589)) ちなみに オーバーライドするために CORE::GLOBAL::を使うのはあまり良い方法とは言えません。システム全体を変更してしまうためです。 (もちろん必要ならやっていいのですが) 変更を限定するために 同じ名前で関数を定義し&を付けて呼び出すことで普通はことたります。

TheBlackArtist
質問者

お礼

オーバーライドできない関数が沢山あったんですね・・・ できないのなら仕方がないですね。 大変勉強になりました。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • Perlでオーバーライド?

    perlでオーバーロードやオーバーライドのようなことがしたいのですが、可能でしょうか? 今はオーバーロードのようなことをしたいのですが Encodeのdecode関数で sub decode{ return Encode::is_utf8($_) ? $_ : encode($_); } のようなことがしたいです。しかし上の例では再帰になります。

    • ベストアンサー
    • Perl
  • オブジェクト? perlをオーバーライドする方法?

    perl 5.6を使っております。 Perl5.8では PerlIOが入出力の際に文字コードを自動変換しているのですが この機能を5.6でもスクリプト互換で使いたい(スクリプトを5.6と5.8を同じにする)のですが、 既存のprint, getc, read, write関数をオーバーライド?することは可能でしょうか? 一々、if(5.8 <= $])としたくないためです。 例えば、外部がeucでperl処理がutf8の場合 sub getc{ return Jcode->new(...)->utf8; } sub print{ return Jcode->new(...)->euc; } sub read{ return Jcode->new(...)->utf8; } sub write{ return Jcode->new(...)->euc; }

    • ベストアンサー
    • Perl
  • 標準関数printの動作をカスタマイズしたい

    mod_perl環境下でprintが$r->print()で置き換えられるのと同様に、通常のスクリプトでCORE::printの動作を変更する方法ってありますか? 例えば、s/java/perl/ を噛ましてから出力するようにする方法を教えて下さい。 mainパッケージだけではなく、他のモジュール内から呼ばれる標準関数のprintにも影響させたいです。

  • Perlで自分自身の関数名を知るには?

    Perlで、自分自身の関数名を知る方法はあるでしょうか? sub testfunc { print FUNCNAME } &testfunc; 例えば、上記のようなコードを実行すると、testfunc という出力が得られるような FUNCNAME のような関数やモジュールがあるか、と言い換えてもいいかもしれません。 以上よろしくお願いします。

    • ベストアンサー
    • Perl
  • Perlで定義されている関数名を全て取得する方法

    Perlで定義されている関数名を全て取得する方法はあるのでしょうか? ソースを見ればわかりますが、取得する方法があれば教えてください。 001.pl sub aaa{ print "a"; } 002.pl sub bbb{ print "b"; }

    • ベストアンサー
    • Perl
  • dieやPerl自体でエラーが発生したときに、独自のルーチンを呼び出す方法

    WindowsのActivePerl5.6を使っています。dieやdieやPerl自体でエラーが発生したときに、通常なら標準エラーに出力して、abortされるが、標準エラーを出力する前に独自の関数を実行させて終わらせることは可能でしょうか? 例えば、以下は可能でしょうか? sub myerror{ print "フック?\n"; goto MyJump; } print "TEST1\n"; die "これを表示させずに、別の処理(フックする方法)" ; # 標準エラーが出力されて終わる。 MyJump: print "TEST2 ここまで表示\n"; Linuxならできるのでしょうか?

    • ベストアンサー
    • Perl
  • perlでサブルーチンへの複数の配列渡し

    perlでサブルーチンに配列を渡しているのですが、 引数としている配列が1個の場合は問題ないのですが、 複数渡すと、第2引数以降が渡りません。 どの様にすれば上手くできますか。 例1 #!/usr/bin/perl @x1 = (14, 11, 5, 12, 8, 15); @x2 = (12, 10, 8, 9); print "main : @x1 \n"; &test(@x1); sub test { my (@arg1) = @_; print "sub : @arg1 \n"; } 結果 main : 14 11 5 12 8 15 sub : 14 11 5 12 8 15 例2 #!/usr/bin/perl @x1 = (14, 11, 5, 12, 8, 15); @x2 = (12, 10, 8, 9); print "main : @x1 \n"; print "main : @x2 \n"; &test(@x1, @x2); sub test { my (@arg1, @arg2) = @_; print "sub : @arg1 \n"; print "sub : @arg2 \n"; } 結果 main : 14 11 5 12 8 15 main : 12 10 8 9 sub : 14 11 5 12 8 15 12 10 8 9 sub : 引数1に全てが設定されて、引数2に設定されていない。

    • ベストアンサー
    • Perl
  • $_ と local($_)

    sub a1{ $x = "abcd"; &a2(\$x); } sub a2{ ($_) = @_; $$_ =~ s/a/z/g; } sub b1{ $x = "abcd"; &b2(\$x); } sub b2{ local($_) = @_; $$_ =~ s/a/c/g; } で、a1とb2についてベンチマークをとった結果、なぜかb1の方が微妙に速いことがわかりました。a関数郡とb関数郡のソース上の位置を逆転させても結果は同じです。回数は、10000000 回カウントした結果です。期待とは違った結果に驚いています。 localは「$_等の特殊記号に一時的な変更を与える」という意味だ過去によんだ「らくだ本」に書いてあった気がするので、この余分な作業でlocalをしたほうが時間がかかると思っていたのですが・・。 これは内部でどういったことが起こっているのでしょうか? もしくはベンチマークするサブルーチンの例がまずかったでしょうか?

    • ベストアンサー
    • Perl
  • 正規表現で文字クラスの引き算

    お世話になります。 正規表現の文字クラスについてお聞きします。 0~6 の数字1字を [0-6] という風に指定しますが、 .NET 正規表現では、 この中から 3~5 は除く、というようなとき、 [0-6-[3-5]] と言う風に書けるようですが、 Perl では書けないようです。 (一応ラクダ本と perldoc perlre には当たりました) #! perl # regtest.pl -- 正規表現のテスト while(<DATA>) { chomp; print "$_ matches /[0-6-[3-5]/\n" if /[0-6-[3-4]/; } __DATA__ 0 1 2 3 4 5 6 7 8 9 のようなスクリプトを動かすと、 C:\test>regtest.pl 0 matches /[0-6-[3-5]/ 1 matches /[0-6-[3-5]/ 2 matches /[0-6-[3-5]/ 3 matches /[0-6-[3-5]/ 4 matches /[0-6-[3-5]/ 5 matches /[0-6-[3-5]/ 6 matches /[0-6-[3-5]/ のような結果が得られ、引き算が確かに聞いていません。 Perl と .NET 正規表現は互換ではないのでしょうか。 また、Perl でも同じことが書けるでしょうか。 よろしくご教示願います。

    • ベストアンサー
    • Perl
  • log2の「正確な」計算方法

    perlでlog2を計算するにはどのようにしたらよいのでしょうか。 perldocによると sub log2 { my $n =shift; return log($n)/log(2); } でよいはずですが、log2 が「正しく整数を返すかどうか」は保証されていないので、時として問題があるようです。 通常、log2 の結果 $a を単に print $a などとして出力する分には Perl が適当? に判断して丸め処理をしてる傾向があるようですが、これを printf "%d", $a とすると、本当に整数部だけが出力され、演算精度によっては意図 しない数値になる場合があるとのこと、計算機環境にインストール した Perlで、演算精度を上げるオプションを追加した場合などで、実際に出力結果が異なる、との報告を受けました。 宜しくお願い致します。

    • ベストアンサー
    • Perl