その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

Test::Fluent::Logger書いた

表題の通りです.Perl5の話です.

CPANにもあげてあります.

https://metacpan.org/pod/Test::Fluent::Logger

何をするモジュールかというと,useするだけでFluent::Loggerのpost及びpost_with_timeの内容をインターセプトして,本来送るべき宛先には送らずに内部のリストにそれを貯めるという動作をするモジュールです.そしてそのリストをgetしてきて中身を確認したり,またリストを空にする (clear) こともできます.
使い方についてはSYNOPSISを読んでいただければわかると思います.とくに難しいことはありません.

本来はMockみたいな名前をつけるべきだったのかもしれませんが,こんなのテスト用途以外に誰が使うんだということでこの名前になっています.
毎度毎度この手のコードを書いていて,良い加減飽きたなという動機でこのたびモジュール化した次第.久々にCPANに新しいモジュールをアップロードしたんですが,昔のあの日のまま変わっていなくて少し安心しました.
ご利用くださいませ.

YAPC::Asia Tokyo 2015 で Yet Another Perl Cooking というタイトルで話してきました

話してきました.以下がスライドとなります.登録時にスライド字幕を誤って「英語」にしてしまったばかりに英語スライドとなっております.
「画像がヤベえ!!」とか言われたんですが,まあこれで発表したんだし公開するスライドの画像を修正するのも違うよな〜と思ったんで無修正版でお届けします.

www.slideshare.net

PDFにしたらデモ (途中でコンソールの画面になるところ) が動かないことに気づいたので gif で.

f:id:moznion:20150822113521g:plain

f:id:moznion:20150822113714g:plain

予想以上に料理の話をしています.前半10分は料理の話をしました.後半は (アブない) 自作調理器の話をしています.
今回の発表は僕の行ったプレゼンテーション史上最高の発表になったのでは無いかと思っていて,個人的に強い手応えを感じています.予想外に会場が盛り上がったというのが大きいわけですが.
スライドだけ見てもあまり良くわからないと思うので,後日公開される発表動画などを見てもらいたいな〜と思っています.


なお,このスライドや発表の内容については不正確な事がままあると思っていて (特に調理温度のあたりとか.ここらへんには正解が無いというか,食中毒リスクを0にしていくというのは極めて難しい話題で,往々にして確率の話になってしまいます.この辺は都度紹介した Cooking for Geeks あたりを参照してもらえれば良いかなあと思います),これを真に受けてエラい事になっても責任を負いかねるという事だけを表明しておきます.自己責任でお願いします!!!!!!


ところで「風呂場で料理をすると熱いお湯がシャワーで大量に出せて便利」という事を言ったんですが皆さんひいてましたね,風呂場で料理をするのは一般的ではないというか,一般的にはやってはならないことだということがわかりました.


[追記]
トーク中言及したんですが,電源ハックの所は本来ヒューズが必要です.ヒューズが飛んで,手持ちのヒューズがなくなり,しかしYAPCは迫ってくるし仕事は山積! ということで泣く泣くヒューズを省略したのです.皆さん必ずヒューズを付けましょう.

plenv で stableperl を利用するの術 & stableperl の話

[追記]
(旧タイトル) Perl::Build (plenv) で stableperl が利用できるようになりました & stableperl の話

色々あって方法が変わったので内容を修正します


Perl::Build (plenv) で stableperl が利用できるようになりました & stableperl の話

Perl::Build 及び plenv で stableperl を取り扱うことが可能になりました.
Perl::Build 1.11 以降で stableperl 対応が有効になっています.

Perl::Build 側に Perl::Build->install_from_stableperl() というメソッドが追加されているので,
それを利用すると stableperl の tar玉をダウンロードして展開してビルドしてインストール,という事ができます.

また,最新の Perl::Build を plenv の build plugin として使用すると stableperl を plenv から
取り扱うことが可能となります.
こんな感じ;

$plenv install -l
Available versions:
 5.6.0
 5.6.1-TRIAL1
 5.6.1-TRIAL2
 5.6.1-TRIAL3
 5.6.1
 5.6.2
 ...
 stableperl-5.22.0-1.001

ご利用される方はご利用下さい.

そんなことをしなくても

$ plenv install --as=stableperl-5.22.0 http://stableperl.schmorp.de/dist/stableperl-5.22.0-1.001.tar.gz

このようにすれば入ります!!!!!!
(Thank you @miyagawa)

[追記ここまで]

stableperl について

stableperl の日本語の資料があんまり無いので併記しておきます.


stableperl についての情報は以下のウェブページを見るのが手っ取り早いと思います.


最初の一文を借用して stableperl を説明するならば
perlの安定性と互換性をオフィシャルのPerlポリシーに記載されたレベルにまで引き上げる (取り戻す)」
ことを目的とした distribution と言うことが出来るでしょう.
stableperl は standard perl の fork であり,AnyEvent や Coro, JSON::XS の作者で知られるところの
Marc Lehmann さんがメンテナを務めています.


特徴としては

  • 通常のメンテナンス期限を超えてもサポートされる *1
  • 後方互換性を *大変* 重視している
  • standard perl が修正を放棄したいくつかのバグを修正する (つもり)
  • 新機能の導入に対する意欲は低い.重要な修正については行う

というものが挙げられるでしょう.


こうした fork 版が出るに至った経緯ですが,これは上掲の記事中で再三示されているように
perl の互換性が (standard) perl 5.22 で損なわれたためです.
perl 5.22 は PP のレベルでは互換性が保たれていますが,内部実装に大きく手が加わったため,
内部 API を利用しているような凝った XS モジュールの中には正常に動作しなくなったものが出てきました.
例としては,Lehmann 氏の Coro や gfx 氏の Mouse (ただし ithread 環境下での話),
またそうした Mouse の問題に伴い Text::Xslate などが挙げられます.恐らく他にもあることでしょう.

そうした状況に Lehmann 氏が業を煮やした為に *2 *3
この度 stableperl という互換性維持を旗印にした fork 版が出たというのが経緯と見ることができます.


さて,そうした状況になってきたので我々はどうするべきかを考える必要があります.

stableperl は互換性が維持され,重要な修正 (fatal なバグ修正などでしょう) が入ることもアナウンスされ,
なおかつ通常の EOL 期日を超えてもサポートされることがポリシーとして掲げられていますから,
これを使っていくというのはひとつの手かもしれません.

しかしながら,「新機能を導入するモチベーションが低い」と書かれていることからも,
今後の standard perl との乖離が進んでいくことは必至でしょう.
なおかつ現状は stableperl は Lehmann 氏が1人でメンテナンスしているようなので *4
Lehmann 氏にがこの活動に飽きたり,あるいは何らかの事情でメンテナンスを続行できない状況になってしまったらゲームセットとなってしまいます.
そうなってしまった時に,じゃあ stableperl から standard perl に戻すぞ! となっても
その時の移行コストやリスクは決して低いものではないことが予想されます.


ので,

  • どうしても Coro (とかその他の動かないモジュール) を動かしたい時は stableperl を使う (あるいは standard perl の 5.20 以前を使う)
  • 動かないモジュールを別の代替モジュールに切り替えていく (standard perl に寄せていく)
  • Coro (とかその他の動かないモジュール) を動くように直す,あるいはそれらが直る事を祈る (standard perl に寄せていく)
  • あきらめる

あたりが落とし所なのかな〜という見方をしています (しかし Coro が直る未来が見えない).
個人的には動かないモジュールを別のモジュールに切り替えていくのが現実的な線なのかなあ,という気がしています (なお Text::Xslate は次の Major バージョンアップで Moo 化される見込みで,Mouse 由来の問題は解消される予定とのこと).


しかしながら今後 stableperl がどうなっていくかは分からないので,動静を見守る必要があるでしょう.
以上です.

*1:予定だと思います

*2:業を煮やした様子については上掲記事のこのパラグラフが分かりやすいでしょう; "Simply because the new set of perl 5 porters (the people maintaining the standard version of perl 5) have an abysmal track record of providing stable releases. They ignore the long-standing policy of keeping compatibility to existing code, and regularly break dozens or even hundreds of modules in new releases, often at a whim, stating they break things as they wish."

*3:とはいえ内部 API を触っているんだから……という意見もある

*4:映画 300 <スリーハンドレッド> を彷彿とさせますね

文字列内のバックスラッシュを区別したい的な

タイトルが適当すぎて何を言っているのかわからないと思いますが,まあそういう事がごくごく稀にあります.結論から言うとヒアドキュメント使えば良いです.

以下の様な文字列を考えた時,

my $string = '\n\\';

これを1文字ずつ処理しようとすると,

say $_ for split //, $string;
# 以下出力
# \
# n
# \

という風になります.

さてこうした時,エスケープの為のバックスラッシュと純粋なバックスラッシュ (つまりエスケープされたバックスラッシュ) との区別がつかなくて困るということがごく稀に生じます.エッ,生じない? 俺はRegexp::Lexerで生じたんだよ!!!!

で,困ったので以下のように解決しました.

use B;

# 文字列をregexp quotedな変数にする
my $string = qr(\n\\);

# B::cstringでバックスラッシュをさらにエスケープする
my $cstring = B::cstring($string); # => '"(?^:\\n\\\\)"'

# 先頭の `"(` と末尾の `)"` が邪魔なので消しておく
$cstring = substr(substr($cstring, 2), 0, -2);

# B::cstringはダブルクォート文字もエスケープするのでそれは元に戻しておく
$cstring =~ s/\\"/"/g;

# 正規表現のmodifierが邪魔なので消す
$cstring =~ s/\A[?]([^:]*)://;

# 余計なバックスラッシュをまとめる
$cstring =~ s/\\\\/\\/g;

と処理してやって,一文字ずつ処理してやると

\
n
\
\

という具合にめでたくエスケープの為のバックスラッシュと純粋なバックスラッシュが区別できるという塩梅です.
reqexp quotedな変数にする*1 というのとB::cstring()を使う*2 という方法に至ったのですが,実際にはヒアドキュメントを使うと楽.

my $string = <'...';
\n\\
...
say $_ for split //, $string;
# \
# n
# \
# \

ヒアドキュメントを使うとこういう七面倒臭いことをしなくても済みます!!!
ヒアドキュメントを使える場面では使ったほうが良さそう! とは言え色々事情はあると思うので適宜使い分けという感じで.

*1:今回はたまたま解析対象が正規表現だからこれでも問題なかったけど……

*2:ちなみにB::cstring()を使っているのは文字列中の改行とかに対応するため

Regexp::Lexerってやつを書いた

https://metacpan.org/pod/Regexp::Lexer
https://github.com/moznion/Regexp-Lexer


Perl正規表現を解析したいなー,と思った時にまず目につくのはRegexp::Parserだと思うのですが,このモジュールは解釈できないメタ文字や構文が多い為,実用にあたってはかなり厳しいという印象があります (モンキーパッチなんかを当てまくると使えるかなって感じ).
ついでに言うと,メンテナのTODDR氏がここで言っているように,氏はこういった分野にあまり明るくないらしく,積極的なメンテナンスが成される可能性は高くありません.パッチを送ろうとも思いましたが,結構複雑なことをやっているモジュールなのでモチベーションがもげた……


で,Regexp::Parserで頑張るのつらいし,それほどもりもりで機能要らないから自分の欲しい機能だけ搭載したミニマルな解析器が欲しいよね〜ってなった時に,まあとにかく自分で書くしかねえかなーと思って,ひとまずその前段階としてRegexp::Lexerというモジュールをしたためました.
名前の通り,正規表現文字列 (正確にはregexp quotedな文字列) を食べて,それをトークン列に分割して返してくれる君です.


このモジュールが吐き出すトークン列を煮るなり焼くなりして自分だけの解析器を作って育てて戦わせれば良いのでは,という思想のもとに生まれました.
とは言えやはりパーザ実装があると便利なので,次はパーザを書きたいという気持ちでいっぱいですが,Regexp::Parserという名前空間を取られているのでどうしたもんかと悩んでいる今日このごろです.何か良い名前あったら教えて下さい.

Excel::Writer::XLSXのset_optimization()について

基本的にExcel::Writer::XLSX使うときは

my $workbook = Excel::Writer::XLSX->new('yabai.xlsx');
my $worksheet = $workbook->add_worksheet();
...

みたいな感じで使うと思うんですが,素朴にこれでやっていこうとするとExcelの行数が増えた時にメモリをバカ食いしてしまって,最悪の場合死に至ります.実際さっき死んだ.

そこでどうするかというと,set_optimization()というメソッドadd_worksheet()する前に呼んでやると良いです.

my $workbook = Excel::Writer::XLSX->new('yabai.xlsx');
$workbook->set_optimization();
my $worksheet = $workbook->add_worksheet();
...

PODにも

The "set_optimization()" method is used to turn on optimizations in the
Excel::Writer::XLSX module. Currently there is only one optimization
available and that is to reduce memory usage.

とあるように,現在のところ使用メモリ量を削減するための手立てはこれしか無いので使うほかないです.

トレードオフとしては,「既にセルに書き込まれているデータについて操作するいくつかの処理が動かない」というのがあって,これはぶっちゃけテーブル関係の処理が動かなくなるという意味なんですが,実際のところPerl経由でテーブル関係の処理とか滅多に使わないし,万が一使う事になってもそれはその時になってから考えればよろしいので,とりあえず何も考えずにset_optimization()を呼んでおけば良いという認識です.行数が多い時は速度も速くなるようですし

とにかく重要なのは,ドキュメントにあるようにadd_worksheet()する前にset_optimization()しなければならないということです.逆だと最適化が働かないので.

YAPC::Asia Tokyo 2014に参加致しました

YAPC::Asia Tokyo 2014に参加致しました.

例年はgihyo.jpのリポータという事で参加していたのですが,今年は僕の怠慢でリポータではなく,初の一般参加でした.

とはいえ,
YAPC::Asia Tokyo 2014でPerl::Lintについて喋りました - その手の平は尻もつかめるさ
に書いたように発表はしたのですが,各方面から「慢談だ,慢談だ」などと揶揄され非常に厳しい状況です.慢談じゃねえっつってんだろ!!!
汚名をすすぐ為に後ほど詳しい解説記事を書く予定です.乞うご期待.


ああ,そうそう,@さんのライブコーディングの茶々入れ係もやりました.
トラブルはありながらも適切に説明を入れながら,時間通りに成果物を完成させてしまうsongmuさんは完全にバケモノだと思いました.
ところで,まじめにライブコーディングやってる人に茶々を入れるの,実は皆さんが思っているより200倍は難しくて,「ここで変なこと言って邪魔したら殺されるんじゃねえか……」という葛藤が常に頭にあったことを述懐します.しかし常に会場がシーンとしているのも怖い……喋らねば! みたいな感じでおっかなびっくりしゃべっていたというのが舞台裏です!!


さて,はじめて一般目線でYAPCに参加しましたが,好きなときに好きなトークを見て,おしゃべりしたい人とおしゃべりできる,というのは本当に良いですね.今年のトークの方はPerl関連のトークと非Perlのトークが半々くらいで,バラエティに富んでて非常に面白かったように感じます.

特に@cho45さんのトークは今年見たトークの中で最高のトークでした.これが本物のハッカーなのだ,と実感しました.ローレイヤーでブログツールを書くという発想がすさまじい.本当に格好いい.

@lestrratさんのSubroutine Signaturesのトークもめちゃめちゃ面白かった.現実はドラマよりもドラマだったし,OSSは人間そのものだという事を改めて実感できました.人間としてのパワーを高めたい.

そして静的解析友達でもある@hitode909さんのトークは,今回の僕のトークと同じ感じのテーマ性を有していたので非常に楽しみにしていて,果たしてそのトークは本当に良かったです.頑張って静的解析するぞ!!!!!


さてさて,今回のYAPCで特筆すべきは今年から導入された同時通訳で,これがとにかく凄い.
こういうカンファレンスで提供される同時通訳と言えば,あまりクオリティが高くなくて,聞いてるうちにその通訳音声がノイズになってきて「だったら自分の耳で聞くわい!!!」ってなってインカムを外す,というのがお決まりのパターンだったわけで.
そんな感じで本当に失礼なことに,YAPCの同時通訳に関しても最初は全く期待していませんでした.
そして蓋をあけるとびっくり仰天,なんと快適な同時通訳! 今まで体験した同時通訳の中で最高の通訳でした.本当にありがとうございます.

例年は海外からのスピーカーのトークは聞きに来る人が少なくてなんだか寂しい思いをしていたのですが,今回は同時通訳のパワーのお陰か聴講者の数が多くて良い感じでした.やはりなんだかんだ言っても言語が違うというハードルは確かにそこに存在するので,このような障壁を少しでも取り除こうとする取り組みは本当に素晴らしいですね.最高です.
かなりのコストがかかっている事と存じますが,来年以降も同時通訳はぜひとも続けていただきたく思います.


そしてインターネット!
我々はインターネットが無いと窒息して死んでしまう民族なわけですが,今回の会場内のWi-Fiは何一つ不自由すること無く,快適なインターネットライフを送ることが出来ました.これが有志の皆さんの力で成り立ってるというのだからすさまじい.マジ最高!! ありがとうございます.


後,無限コーヒーや無限かき氷といった炊き出し制度もかなり良かったです.
ああいう食物や飲料が存在しているとどこからともなく自然と人がわらわらと集まってくるので,そこで自然とコミュニケーションが生まれて色々おもしろ体験が出来て良い.僕はといえばその無限コーヒーの傍らでBooking.comの人事の人と適当な英語で魂のコミュニケーションを行い,Booking.comのロゴが入ったスクィーズボトルを貰うにまでこぎつけました.「そのボトルあげたんだから雇うぞ」とか言われた気がするけど多分気のせいだ.
そういった場所でおもしろイベントを催すっていうのも,「これぞ祭りじゃ!!」という気分が盛り上がって非常に良かった.


会場内にHUBがあるというのは非常に考えものですね!! 僕みたいに自制心の無い人間はホイホイおびき寄せられてしまう!
とは言えこういう社交場というか,コミュニケーションの場があるのは本当に素晴らしい.普段話せないような色々な人と楽しく話せて本当に良かった.
酔っ払った勢いでBooking.comの皆さんと喋ってたら「雇うぞ」とか言われた気がするけど多分気のせいだ.


とにかく今年のYAPC,楽しみ倒しました.ありがとうございます.
来年も是非参加したいと思います!!


最後にひと言
適当な英語でも通じる!!!!!!!!!!!!!