だるろぐ

だるいぶろぐです

さっき書いた「use if $COND, MODULE」が間違ってたのでもう一度

http://d.hatena.ne.jp/hirafoo/20110529/1306600000 を書いたら即行でxaicronさんからコメントを頂いた。
自分は

use if

のifをビルトイン関数のifだと思ったけど、ビルトイン関数のifはこんな使い方はできない。後置ifは使えるけど。


で、教わったとおり if.pm を見る。

package if;

$VERSION = '0.05';

sub work {
  my $method = shift() ? 'import' : 'unimport';
  die "Too few arguments to `use if' (some code returning an empty list in list context?)"
    unless @_ >= 2;
  return unless shift;      # CONDITION

  my $p = $_[0];        # PACKAGE
  (my $file = "$p.pm") =~ s!::!/!g;
  require $file;        # Works even if $_[0] is a keyword (like open)
  my $m = $p->can($method);
  goto &$m if $m;
}

sub import   { shift; unshift @_, 1; goto &work }
sub unimport { shift; unshift @_, 0; goto &work }

1;

5.8.8付属のif.pmはこれ。cpanには最新版の0.0601があったけど、違いは作者のメールアドレスだけだった。
さて読む。

読む

短いし簡単だけどまぁ読む。

sub import   { shift; unshift @_, 1; goto &work }
sub unimport { shift; unshift @_, 0; goto &work }

この空の "shift;" は、 "if" という文字列。if.pm は

use if 1, "CGI";

とかして使うわけだけど、use は

BEGIN { require Module; import Module LIST; }

に等しいので、importの第一引数は呼び出しもとのパッケージ名が入る。から。

  my $method = shift() ? 'import' : 'unimport';
  die "Too few arguments to `use if' (some code returning an empty list in list context?)"
    unless @_ >= 2;
  return unless shift;      # CONDITION

この shift() の値は goto する直前に unshift している、 1 もしくは 0 が入る。
で、 if.pm を使うときは少なくとも、評価する式とuseするモジュール名の計2つの引数が要るので、引数が2個以上無ければdieして終わり。
評価する式が偽だったらreturnで終わり。


あとはパッケージ名を Hoge::Huga みたいなのを Hoge/Huga にする。use はコロン区切りだけど、requireはスラッシュ区切りなので。
そしてrequireしてimport/unimportが呼べるなら呼んで終わり。


終わり。

その1

parent.pm読んだ時も思ったけど、この手のモジュールは短いのによくやるなと感心。
でも use strict くらいしてもいいと思うんだ。

その2

明らかに後置ifじゃないのにビルトインのifだと勘違いしたのは眠かったからだそれならしょうがないなしょうがないよね!

その3

元のエントリに追記だと、RSSリーダーで元のエントリを既に読んだ人が気付かないのでもう一度エントリを書いた。
自分も過去に人のブログ読んでて、追記に気付かず、えらい後になってたまたま気付いたことがある。
というのを学習したので、自分も以前はわざわざエントリ起こすのではなく追記していたけど、しなくなった。