Subscribed unsubscribe Subscribe Subscribe

Perlスクリプトをワンライナー化するモジュールAcme::OneLinerを作ってみた

GitHubにおいてます。
GitHub - sugyan/Acme-OneLiner: ワンライナー生成モジュール


たとえばhello.plというスクリプトを用意して

#!/usr/bin/perl
use strict;
use warnings;

print 'Hello world!', "\n"; 

Acme::OneLinerをuseして実行すると、ワンライナーに変換してくれます。

$ perl -MAcme::OneLiner hello.pl
perl -e 'use warnings; use strict q/refs/; print q/Hello world!/, "\n";'

出力結果をそのままコピペしてコマンド実行すればスクリプトの実行と同じ結果が得られる…はず。

作成の経緯

スクリプトワンライナーに変換できないかなー

基本的に行末はセミコロンで区切ってあるし、改行を削除して繋げるだけで1行になるんじゃね?

コメント行が邪魔だな。コメント部分だけ取り除いてやる必要があるな

'#'から始まる行はともかく、行の途中からコメントに入るところが判別しにくいな

クォートとかヒアドキュメント内の'#'を区別しないといけないし、これは厳しい

自分でparseするのはかなり無理があるぞ

そうだ、B::Deparseっていうモジュールがあるよね

あれで一度Deparseすれば、コメント部分を取り除いてくれる!

'-MO=Deparse'ってやったときに何が起こっているんだろう

ふむふむ。Oモジュールからimport時にB::Deparse::compileってのを呼んでるのね。

そんでB::Deparse::compileの中ではよく分からんけどparseした結果をprintしていってるのか

じゃあまずはB::Deparse::compileのprint出力を内部で捕まえる必要があるな。

tieを使うとか、色々方法があるらしい。IO::CaptureOutputってのを使ってみよう

よし、B::Deparse::compileでのSTDOUT出力を得られたぞ。

改行を削除して1行に繋げるだけ!

…の前に、シングルクォートを使われると困るので置換しておこう

よし、とりあえずできた!


という流れで作りました。

課題

まだ検証が不十分なのでちゃんと変換できない、もしくは変換できても動作がおかしい、という場合があると思います。
こういうモジュールの場合、どうやってテストを書けば良いんだろう?