エンジニアが発信する【Perl】の記事を集めました

エンジニアが作る最新ITブログ トップ>エンジニアの発信する【Perl】

2009年11月30日

[Shibuya.pm]TechTalk#12

Shibuya Perl Mongers : Shibuya Perl Mongersテクニカルトーク#12 NoSQL特集

行く予定は無かったんですが、ひょんなことから参加することにしました。

まぁ会場が家の隣なので行こうかな的なノリですが。。。

滑り込み登録ズサ━━━━⊂(゜Д゜⊂⌒`つ≡≡≡━━━━!!

2009年06月03日

[Perl]voidコンテキストの使われ方

まあ、PP のモジュールが void context であることを判定につかってるケースってほとんどないんですけどね。 Class::Method::Modifiers 1.01 が void context をみてない件 - TokuLog 改めB日記

ないですねぇ。自分もそんなの書かないし。

ちなみにClass-MOPではlib/Class/MOP/Method/Wrapped.pmでvoidコンテキスト関連の処理が書かれてますね。(前のエントリの最後に書いたのと同じ用途)

ラップ系はvoidコンテキストの面倒を見ないといけないですからね。



これまでの流れだと「そもそもvoidコンテキストって何に使うねん」って思ってる人もいそうなので例を挙げておきます。

voidコンテキストの実用例としては、例えばPod::Simple::RTF(Perl5.9.3以降ならコアモジュール)にあって、lib/Pod/Simple/RTF.pmのsub rtf_escで出現します。コメントも付いてて処理も平易なので、何やってるかは見れば分かると思います。

あんまり行儀が良いとは思えないですけど、その一方で、書き手の意図(文脈=コンテキスト)に応じてよしなにしてくれる感じがPerlらしいなあとも思ったりします。


また少し違う使い方の例でData::Dumpがあって、Data::Dump::dumpは

dump($foo);      # STDERRにprintする
$x = dump($foo); # printしないで値を$xに返す

という2種類の書き方ができるんですが、それを実現するためにvoidコンテキストによる振り分けが行われています。(lib/Data/Dump.pmのsub dump)

普通に考えるとこういうのはvoidコンテキストに頼らずに

print STDERR dump($foo);
$x = dump($foo);

のように呼び出し側で明確に処理を書くようなインターフェイスにしますよね。もしくは生成用のメソッドと出力用のメソッドを別にして

# sub dumpがprintしないようにしておいて、
package Data::Dump;
sub p {
  print STDERR dump(@_);
}

とか。(だから自分ではvoidコンテキストを使った処理をあまり書いた事ないし、皆も書かないんだと思います)

まぁ「だいたいデバッグ用途で使うだろう」というData::Dumpの役割を考えると、「dump($foo)」って簡潔に書ける方が良いと思ったからなんでしょうね。




ここまで書いてて「コンテキストを拡張するモジュールあったんだけど何だったかなあ」って気になったので調べてみたら、Damian先生のContextual::Returnでした。ドキュメント読むだけでもワクワクします。ただレビュー見たら「こんなの使うのお勧めしないよ!」って書いてあった。自分もそう思います(笑)


ついでにレビューの中で見つけたこれ→PBP Module Recommendation Commentary / Perl 5 Wiki 初めて見ました。何か良さそう。収穫収穫。

2009年05月31日

[Perl]MANIFEST.SKIPを、最新のもの+自前のものにする

色々書きたいもの溜まってるけど、さっきやったExtUtilsに関する修正を書いてみる。


自前のMANIFEST.SKIPが無い場合、ExtUtils-Manifestに同梱されているものが使われる。で、自前のMANIFEST.SKIPを普通に作ってしまうと、ExtUtils-Manifestの方で更新されても追従できなくなってしまう。


そこで、MYの仕組みを使ってこういうの↓をMakefile.PLに書いた。

use File::Basename qw(dirname);

sub MY::dist_basics {
    my ( $self, @args ) = @_;
    my $dist_basics = $self->MM::dist_basics(@args);

    $dist_basics =~ s{^(manifest/\/is*:.*?)$}{$1 MANIFEST.SKIP}msx;

    ( my $format = <<'END_OF_DIST_BASICS') =~ s/^[ ]{4}//\/it/gmsx;
MANIFEST.SKIP: %s/MANIFEST.SKIP
    cat $< > $@
    echo '# Avoid archives of this distribution' >> $@
    echo '^%s-' >> $@
END_OF_DIST_BASICS

    $dist_basics .= sprintf $format, dirname( $self->{MAKEMAKER} ),
      $self->{FULLEXT};

    return $dist_basics;
}

(ちなみに (my $str = '...') =~ s/^[ ]{4}//\/it/gmsx は結構使う。タブ文字と空白文字は混乱の元なので、タブ文字は使わないことにしている)


これでMakefileが

manifest : MANIFEST.SKIP
        $(PERLRUN) "-MExtUtils::Manifest=mkmanifest" -e mkmanifest

MANIFEST.SKIP: /usr/local/lib/perl5/5.10.0/ExtUtils/MANIFEST.SKIP
        cat $< > $@
        echo '# Avoid archives of this distribution' >> $@
        echo '^MyApp-' >> $@

となるので、make manifestする度に最新のMANIFEST.SKIPに追従できる。

2009年05月11日

[Perl][Catalyst]Catalyst::Runtimeのバージョンチェックをしているようでしていない件

Catalyst::Helperが出力するMyApp.pmに、

use Catalyst::Runtime '5.70';

ってあるじゃないですか。

あまりHelper使わないから気付かなかったけど、良く見たら文字列になってるんですよね。ってことは、Catalyst::Runtimeバージョン5.70以上を要求してるわけじゃなくて、sub importに'5.70'という引数を渡してるだけなんですよ。

これを

use Catalyst::Runtime 5.70;

このように書くとバージョンチェックが働いて、Catalyst::Runtimeのバージョンが5.70未満だとコンパイルエラーになります。

$ perl -e "use Catalyst::Runtime '5.70';";

$ perl -e "use Catalyst::Runtime 5.70;";
Catalyst::Runtime version 5.7 required--this is only version 5.5 at -e line 1.
BEGIN failed--compilation aborted at -e line 1.  # 捏造しました。実際には5.5とかありません。


ちなみにバージョン指定部分はIVじゃないとダメなので。

BEGIN {
  my $ver = 5.70;
  use Catalyst::Runtime $ver;
}

って書いてもバージョンチェックはしてくれないのでご注意を。

2009年05月06日

[Perl][CPAN]Module-Install-0.86のModule::AutoInstallが壊れてるくさい

Adam Kennedy / Module-Install-0.86 - search.cpan.org

perl Makefile.PLしたときに、

*** Module::AutoInstall version 1.03
*** Checking for Perl dependencies...
*** Since we're running under CPAN, I'll just let it take care
    of the dependency's installation later.

と警告が出て、普通はmissingなモジュールがあったら

==> Auto-install the 1 mandatory module(s) from CPAN? [y]

と聞かれるはずが何も聞かれず、自動インストールされなくなっていた。

なんでかなーと思ってデバッグしてたら、

Module/AutoInstall.pm

sub _check_lock {
    (前略)
    require CPAN;

    if ($CPAN::VERSION > '1.89' && $ENV{PERL5_CPAN_IS_RUNNING}) {
        return _running_under('CPAN');
    }
    (後略)

ってなってた。目が点になった。

これではif文が必ず真になってしまう・・・(もちろん0.85まではrequireしてない。ってか0.84〜0.85消えてるし・・・)


駄目だこいつ・・・早くなんとかしないと・・・

2009年04月30日

[Perl][CPAN]CPAN封印

CPANPLUSに最大の敬意を示すため、CPANを使わないという信念に沿ったシステム(なんじゃそりゃ)では、

% rm -rf $HOME/.cpan
% touch $HOME/.cpan
% chmod 0000 $HOME/.cpan

として、CPANを封印すると良いでしょう。(最後のchmodは余分だけど、CPANPLUSへの敬意の表れ)

これで、CPANを使おうものなら

% cpan
mkdir /path/to/.cpan: File exists at /usr/lib/perl5/5.10.0/CPAN/HandleConfig.pm line 539

などと天罰が下るようになります。



ところが、普段CPANPLUS使ってインスコする場合は問題無いのですが、Module::AutoInstall(v1.03)が含まれるMakefile.PLを実行すると、CPANPLUSが利用可能な場合でもとりあえずCPANを起動しやがります。

そんなときはMakefile.PL中でModule::AutoInstallがincludeされる前に

    $CPAN::VERSION = 'to deceive Module::AutoInstall'; # 真だったらなんでもいい

とでもしておけばCPANをロード済みだと勘違いして読み込まなくなります。


いけすかねぇModule::AutoInstallを、無理やりねじ込みhackで騙し切るのは最高に気持ちいーぜ!ヒャッハー!





さすがにそこまでやるのは本末転倒的な感じも否めず、我ながら阿呆だなーと思った。

2009年04月29日

[Perl]Perlから外部コマンドを実行する

最近Perlから外部コマンドを実行する場合は、openやsystemなどを使わずにIPC::Cmdを良く使っている。

特に深い理由はないんだけど、

  • IPC::Cmdは5.009005からコアモジュールに入っている
  • それなりに綺麗に書ける
  • $IPC::Cmd::VERBOSEを真にしておけば、実行するコマンドの内容を出力してくれる
  • 戻り値も「STDOUT,STDERR,その両方」が用意されていて、改行区切りで配列になってるのも地味に便利

 (『かえりち』だと『返り血』に変換されるので、昔から『もどりち』って言うようにしてる>id:amachang

とかかなあ。多分1番目の理由が大きい。コアモジュールに凝ってるのかもしれない。

ログ吐きにはLog::Message::Simple使うようになったし。

まあLog::Message::Simpleは、daemontools付属のmultilogと相性が良いという理由もあるんだけど。


ちなみにコマンドの出力をインタラクティブに処理したいときは、昔はIPC::Runを使っていたけど最近はIPC::Open3を使ってる。理由はIPC::Runがコアモジュールじゃないからってだけなんだけどさ。



あとFile::*系を良く使うようになったなあ。今までシェルスクリプトで書いてたようなものをPerlで書くようになったからだと思う。ウェブアプリ以外はほとんどシェルスクリプトでパッと書いちゃうタイプなんだけど、やっぱたまに面倒くせぇって思うときがあるんだよね。そんなときPerlで書けるのは良い。


おまけだけど、File::Fetchでリモートファイルを取得できるのを最近知ったんだけど、LWPとかwgetとかcurlとかを自動的に選んでくれるから環境によっては地味に便利だよね。まあでもURI::Fetchと違ってキャッシュできんし、結局IO::All使うからあんまり出番無いんだけどさ。




というわけで誰にも聞かれてないけど、最近のマイPerlモジュール事情を軽く話してみました。

2009年04月28日

[Perl][CPAN]DBIx-Class-Schema-Loader-0.04005がインスコできない

のでDEVELOPER RELEASE入れてやったぜヒャッハー!

% cpanp -i I/IL/ILMARI/DBIx-Class-Schema-Loader-0.04999_07.tar.gz

テストがエラーになるんだけども、原因はDBIx::Class::ResultSetManagerが消えるからのようで。

DBIx::Class::ResultSetManagerのdeprecatedに備える - hide-k.net#blog

2009年03月31日

[Perl][Catalyst][Lighttpd]CX::P::E::FastCGI::LighttpdをCPANに上げた

もう1年以上前からになりますが、

lighttpdでファイルが存在しない場合にFastCGI-Catalystへ飛ばす設定とプラグイン - holidays-l開発ブログ

このようなプラグインを使っていました。

この度(主に自分都合により)このプラグインをCPANに0.0.1としてアップしました。

CatalystX::Plugin::Engine::FastCGI::Lighttpd - enable to dispatch to the Catalyst via 404 handler. - search.cpan.org

(これでコピーして回らなくて済む)


そして先ほどアップした0.0.2では、

Lighttpd + mod_proxy で Catalystに飛ばす時 - holidays-l開発ブログ

の記事中

  setenv.add-request-header = ("X-Forwarded-Host" => "backend.example.com")

のようにlighttpd側で処理していたものを、プラグイン側でHTTP_X_FORWARDED_HOSTにHTTP_X_HOSTをセットしてしまうようにしてみました。(lighttpd側でX-Forwarded-Hostをセットしなくても良い)



Catalyst::Engine辺りに仕込むべきなんだろうけど…。とかメーリングリストで言われてるけど気にしない方向で。

あー。当初の目的と既に違っちゃっててdescriptionがおかしく見えるな。まあいいか。

2009年03月26日

[Perl]Re: Shipwrightちょっとだけ使ってみたよ - holidays-l開発ブログ

Shipwrightちょっとだけ使ってみたよ - holidays-l開発ブログ

本当にちょっとだけ使って、その後一切使ってないっす。

コミットされまくるのが嫌だ。

エンジニアが作る最新ITブログ トップ>エンジニアの発信する【Perl】

メンバー紹介

タグパネル

ランキング

エンジニアが作る最新ITブログ DODA