翻訳 CPAN::Meta::Spec、Module::CPANFile、Minilla、Milla::Tutorial、cpanm、Carton、plenv、plenv-contrib
CPANまわりのツールたちの開発が活発なので、翻訳しようと前々から思ってたのですが、ようやく翻訳しました。
- CPAN::Meta::Spec ... CPANメタデータ仕様
- cpanfile ... PerlアプリケーションのためにCPANの依存性を記述するためのフォーマット
- cpanfile-faq ... cpanfile FAQ
- Minilla ... CPANモジュールオーサリングツール
- Minilla::Tutorial ... Minilla チュートリアルドキュメント
- Dist::Milla::Tutorial ... Milla HOW TO
- App::cpanminus ... App::cpanminus
- cpanm ... cpanm コマンド
- Carton ... Carton
- plenv
- plenv-contrib
最初は、cpanfile とMinillaだけのつもりだったんですが CPAN::Meta::Specも文章中に出てくるし、Minilla::Tutorialは、Milla::Tutorialから取ってるとのことだし...ということで、Milla::Tutorialも訳しました...と、芋づる式に色々訳す結果となりました。
追記: cpanm も訳しました。
追記2: Carton も訳しました。
追記3: plenv & plenv-contrib も訳しました。
scalarコンテキストでのsortの振る舞いは未定義
何年も使ってるのに、基本的な関数知らないとか!とか、思った。
同僚がはまっていたので知ったのですが、sort のスカラコンテキストでの振る舞いは未定義だそうです。実際問題、sort をスカラで受けるとか意味わからない。ちゃんと警告も出ます。
Useless use of sort in scalar context at -e line 1.
そもそも、リストをスカラで受けるのは、かなり嫌な感じになるため、経験的に避けます。
my $item = qw/a b c/;
$item に入るのは、リストの最後の要素、'c' なのですが、意図してこんなコードは書きませんよね。
ちなみに、
my ($item) = qw/a b c/;
の場合は、$item に入るのは、'a' です。
grep, map に関しては、要素数が取れるので、また違った感じですが、要素数を取る目的ではあんまり使った覚えがない。grep を scalar コンテキストで使う場合は、だいぶ昔は if の中とかで使ってた気がするけど、そういうケースでは、List::Util の any のほうが良いですね。
if (any {$_ > 1} @array) { # ... }
map をスカラコンテキストで使った覚えがないなぁ。使うケースが思いつかない。
で、sort なのですが、(Ubuntu 13.04で、Perl 5.16.3 と 5.12.3 で試しました)
my $item = sort qw/a b c/;
$item は空になります。perldoc -f sort では、
sort SUBNAME LIST
http://perldoc.jp/func/sort
sort BLOCK LIST
sort LIST
リストコンテキストでは、LIST をソートし、ソートされたリスト値を返します。 スカラコンテキストでは、sort() の振る舞いは未定義です。
「 スカラコンテキストでは、sort() の振る舞いは未定義」なので、空になる保証もないわけですが。
そもそも、リストコンテキスト以外は意味ないからsort自体の処理に入らないようです。
最初の警告の説明には、以下のように書かれています。
Useless use of sort in scalar context
(W void) こんな風に、ソートをスカラコンテキストで使いました:my $x = sort @y;
http://perldoc.jp/docs/perl/perldiag.pod
これは全く便利ではないので、perl は現在のところ最適化して取り除きます。
以下の通り。
$ perl -e 'scalar sort {die($a) } (1,2); ' # scalar context $ perl -e 'sort {die($a) } (1,2); ' # void context $ perl -e 'my @x = sort {die($a) } (1,2); ' # list context 2 at -e line 1.
dieしているのは、最後のものだけでした。
どうでも良いのですが、リスト操作系の関数でスカラコンテキストでは意味無さげな reverse はどうなんだろうと思ったら、こんな感じでした。
print scalar reverse "dlrow ,", "olleH"; # Hello, world
どこで使うのかと小一時間悩みましたが、回文かどうかチェックするのが簡単でした(引用: http://kaibun21.jp/works/13200/)。
perl -CA -e 'print join("", @ARGV) eq reverse(@ARGV);' かいあたえ しつくしくつし えたあいか
もはや、記事名となんの関係もないけど、最後にまとめると、
リスト ... 最後の要素 配列 ... 要素数 sort ... 未定義 grep ... 要素数 map ... 要素数 reverse ... 引数の順番も中身もひっくり返す
て、感じでした。
Teng::Plugin::SearchBySQLAbstractMore 0.10 と 0.11 をリリース
https://metacpan.org/module/Teng::Plugin::SearchBySQLAbstractMore
0.10 は先日ご報告をうけた、search_by_sql_abstract_more メソッドの挙動が、search と違うよっていうバグの修正です(ちなみに、僕はこのバグに依存したコードを書いちゃってたので、修正が必要でした orz)。
0.11 はTengのバージョンが0.17に上がって、_execute メソッドじゃなくて、execute を使いなさいとwarningが出るようになったので、その修正です。
なんで、0.11 は、Teng 0.17 を要求します。別に上げても問題ないと思いますが、一応注意ということで。
(うちのプロダクション環境で、Teng 0.17を動かしてますが、特に問題はありません)。
Teng::Plugin::SearchBySQLAbstractMore 0.09 リリース
https://metacpan.org/module/Teng::Plugin::SearchBySQLAbstractMore
変更点は、create_sql_by_sql_abstract_more ていうのを生やしたのと、Teng::Plugin::SearchBySQLAbstractMore::Pager::Countの改良。
create_sql_by_sql_abstract_more は、そのまま、Tengのsearch形式の引数か、SQL::Abstract::Moreのselectの引数で、単にSQL生成するだけのものです。
Pager::Countは、改良したのですが、レコード多いと使えないので、MySQL使ってるなら、Pager::CountOrMySQLFoundRows か、Pager::MySQLFoundRowsを使ったほうが良いと思います。
(前者は、通常は COUNT(*) を使って、GROUP BY を使ってる時のみ、SQL_CALC_FOUND_ROWSを使います)
まぁ、SQL_CALC_FOUND_ROWS もあんまり評判は良くないですけどね。
spork で作ったスライドをPDFにする
YAPC::Asiaお疲れ様でした!
牧さん、櫛井さん、スピーカーの皆様、来場者の方々、ありがとうございました。
今回は、スタッフとしてRoom 1(中教室)にずっといましたが、仕事してたり、perldoc.jp がバグってるのを見つけたり(deltaが表示できてなかった orz)で、実はちゃんと聞けてなかったりします。ボランティアの仕事もあんまりできてなかったかも。すみません!
気になるトークはまた動画で見ようと思います。
で、1日目のLT、perldoc.jp の10周年のお話を2分でやらせて頂きましたが、2012年というのにspork使ってます。sporkはオワコンという話を聞きましたが(kwiki.org落ちてるし)、kwiki記法は楽なので。
ただ、HTMLだ公開するのが面倒だなぁということで、PhantomJS で HTML のスライドを PDF にし SlideShare にあげる方法を参考に、scriptを作りました。
https://github.com/ktat/tools/blob/master/mkslide
使い方は、
% mkslide perldocjp
みたいな感じにすると、spork -make して、PhantomJS でpng画像にして、sam2p で PDFにして、pdftk で結合して、foxitreader で開く。
という感じで、完全自分用でしかないし、てきとーに作りました。phantomjsに渡す js も、メンテがめんどくさいから、コマンド内に書いちゃって、毎度書き出してるって言う...。S5 plugin を使っているのも前提だし、ディレクトリも固定で、以下のようになります。
~/docs/slides/perldocjp/slides/start.html -> ~/docs/slides/perldocjp/perldocjp.slide.pdf
てわけで、誰も使わないと思いますが、このscriptとは関係なく、PhantomJS は便利そうだなーと思った。
ループ回数が多いときにDateTime使うのはやめよう
ボトルネックを探していたら、5000回くらいのループでDateTimeを使っている場面だったという話。
簡単な例として、1分追加する処理でベンチマークとってみた。
Benchmark: running datetime, timepiece for at least 3 CPU seconds... datetime: 3 wallclock secs ( 3.14 usr + 0.00 sys = 3.14 CPU) @ 2720.70/s (n=8543) timepiece: 4 wallclock secs ( 2.70 usr + 0.55 sys = 3.25 CPU) @ 60119.38/s (n=195388)
5000回のループだったら、DateTimeが1.8秒かかるのに対して、Time::Pieceなら、0.01秒弱。
ベンチマークのコードは下記。
#!/usr/bin/perl use strict; use warnings; use DateTime; use Time::Piece (); use Benchmark qw/cmpthese timethese/; my $time = time; my $dt = DateTime->now(epoch => $time); my $tp = Time::Piece::localtime($time); timethese(0, {datetime => sub { $dt->add(minutes => 1); }, timepiece => sub { $tp += 60; }}, );
実際のコードでは、ループが大きいのはなくせないんだけど、日付の演算を毎回使う必要はなかったので、使う数はだいぶ数は減ったんですけども。
そもそも、epoch time で記録すべきだったとか、今更感漂う今日この頃に orz
YAML::XS 0.35未満のメモリリーク
DBに大きめのYAMLが保存してあって、それを読み取る処理があったのですが、メモリがどんどん増えていくなーと思ったら、以下のものでした。
http://blogs.perl.org/users/brian_d_foy/2011/03/fixing-yamlxss-memory-leak.html
Changesでは、
- -
version: 0.35
date: Mon Apr 4 00:33:09 CST 2011
changes:http://cpansearch.perl.org/src/INGY/YAML-LibYAML-0.38/Changes
- Apply bdfoy patch from rt-46172
- Update ppport.h to fix rt-64749 & rt-62054
- Add ANDK's regexp.t patch from rt-62266
"Apply bdfoy patch from rt-46172"がそれ。1年くらい前には直っている話でした。
というわけで、0.35未満の人は上げたほうが良いですよ。