Perl

minっぽい関数の拡張系

入力としてundefあるいは値を複数受け取り 結果として値の最小値(あるいは値が全てundefの場合はundef)を返す という処理をどう書くのがいいか? 自分が思いつくのは以下のコードだけど、もっといい書き方あるかなぁ(簡潔明快であることが望ましい)。 my…

モジュールがロードできたら、その関数を呼ぶ

って処理を書きたい場合がある*1けど、そういう場合は、 my $access_allowed = eval { require Authen::Libwrap } && host_ctl('tiarra', $sock); みたいな感じでよかったらしい。って id:tokuhirom に教えてもらった *1:たとえば Tiarra (あるいはPerl) か…

alarmをネストする方法

だいたいこんな感じ。結局使わないコードだけど。alarm(0) を呼んでからセットしてるのは、$SIG{ALRM} の差し替え中にシグナルが飛んでくる可能性を考えて。このあたりは自分がセットするシグナルハンドラの仕様によっては、高速化の余地があるはず。 sub cr…

POSIX::_exit を呼べばグローバルデストラクションは走らない

perldoc POSIX には、 _exit This is identical to the C function "_exit()". It exits the program immediately which means among other things buffered I/O is not flushed.としか書いてないけど、もちろん global destruction も走らない。 use strict…

サーバやI/O待ちを含むベンチマークを Benchmark::cmpthese で比較してはいけない、という話

Benchmark.pm の cmpthese は手軽に速度の比較ができるのでとても便利。でも、そもそも何のパフォーマンスを比較しているのか? ソースコードを読めばわかるけど、 perl プロセスのCPU使用時間 あるいは、上記+子プロセスのCPU使用時間 を測定している。換…

初期化とか終了処理とか除いたベンチマークの取り方

ベンチマークを取る際に、それぞれの手法ごとに初期化や終了処理が必要なんだけど、それら処理を除いた、コアの部分の数値を比較したいことって結構ある。そういう場合は、以下のように書けばいい。ということを理解したのでメモ。 #! /usr/bin/perl use str…

メモ: Error.pm でサブクラス化した例外を投げる

例外を投げるときは $obj->throw。ベースクラスは Error::Simple。 try { MyException->new("hello world")->throw; } catch MyException with { my $e = shift; print "$e\n"; }; package MyException; use base qw(Error::Simple); みたく書く、色々教えて…

呼び出し元のコンテキストで eval する方法

String::TT なんかがそうですけど、呼び出し元の変数を使いたい、ということがときどきあります。たとえば、 sub hello_to_alice { my $user = "Alice"; say_hello(); # "Hello to Alice!" と言ってほしい } って書きたいとか、そういうケースですね。結論か…

セキュアな XS ローダー

perl のプロセス内でサンドボックスを作ろうと思うと、少なくとも以下の2点が必要です。 オプコードの制限 DynaLoader::dl_install_xsub を利用したネイティブコード注入 このうち、オプコードの制限については、ops モジュールで行うことが可能です。一方…