前回ブログを書いたときはv1.6.0だったので7個くらいアップデートした。 今回までのアップデートでかなり実用的な機能を実装したので常用にも耐えられるのではなかろうと思う。 v1.7.0だけリリースビルドをミスったのでv1.7.1になっている。しょうがない
主な変更点
--debugを廃止して$RF_DEBUGを参照するようにした
いままでデバッグ用に--debugを用意していたが、オプションパーサーが実行される前にエラーがあるとデバッグプリントできないことに気がついたので、--debugを廃止して$RF_DEBUGがセットされていたらデバッグプリントするようにした。 ちなみに、デバッグを有効にするとバックトレースが表示されるだけである。 もう少しいい感じにしたいが困ったときになんとかする。
JSON/YAMLフィルタに--disable-boolean-modeを追加した
rfにおいてはtrueを返すとレコードをそのまま出力して、false/nilならそのレコードの処理はスキップされる。 しかしJSON/YAMLにおいては、true/false/nullが特別な意味を持っているためrfの処理と一貫性がなくなってしまう。 そこで、通常時はrfの挙動を尊重しtrue/false/nilをレコードを処理するかのフラグとして利用し、--disable-boolean-modeを指定した場合はtrue/false/nullをJSON/YAMLのリテラルとして出力するようにした。 以下実行例
$ echo '"abc"' | rf -j true "abc" $ echo '"abc"' | rf -j --disable-boolean-mode true true
YAML出力時にnullの省略記法(~)を使うのをやめた
rfを作っていて初めて知ったのだが、YAMLにおいてはnullを~
と書くことができる。
最初はバグかなにかかと思って驚いたが後に仕様だということ知った。
どうもmruby-yamlでは~
と入力するようになっていたので、forkしてnullとして出力するようにした。
--with-filename / --with-record-numberオプションの追加
grepにおける--with-filename(-H)と--line-number(-n)と同じ挙動になっている。 色付けするようにしたところがこだわりポイント。
ちなみに、line-numberじゃなくてrecord-numberになっているのは、rfにおいては行単位ではなくレコード単位で処理していることと、JSON/YAMLパーサが行単位で処理できないことでrecord-numberとなっている。
ディレクトリを再帰的に探索する--recursive(-R)オプションを追加した
grepにおける-Rと同じで、引数にしていされたディレクトリを探索していき発見したファイルに対して処理を行う。
rfでの特報的な部分としてJSON/YAMLフィルタでも再帰的な処理ができるようになっている。 今のところ私が思いつくユースケースはないが…
-Rオプションの使用時の注意点なのだが、バイナリファイルを検索し出力してしまうとターミナルがバグってしまう。。。 grepにおいてはバイナリファイルを読み込んだ場合は自動で出力をフィルタするのだがrfはまだ実装していないのであった…。
使用しているmrubyのコミットIDを出力するようにした
mrubyは常に更新されているプロダクトなので常に最新を利用したい。 しかし、mrubyのバージョンのインクリメントは1年に一回のよう(?)なので、どのタイミングのmrubyかわからない。 そこでビルドに使うmrubyに少し変更を加えてコミットIDもでるようにした。
$ rf --version rf 1.13.0 (mruby 3.2.0 9e50d67)
--grep(-g)オプションの追加
rfではRubyでコードを書かないといけないという関係上、正規表現での検索を行おうとする //
をつけなくてはいけない。
$ echo "foo" | rf /foo/ foo
このくらいの検索でわざわざ //
をつけるのはさすがにめんどくさいので引数を正規表現パターンとして解釈するオプションを追加した。
$ echo "foo" | rf -g foo foo
ファイルを置換するオプション--in-place(-i)の追加
sedの-iオプションと同じでファイルを置換するオプションを追加した。
$ cat file foo $ rf -i '"bar"' file $ cat file bar
StringとInteger/Floatを直接比較できるようにした
例えば、ある数値以上の行だけ抜き出したいといった場合に、今までのrfではStringを一旦to_iしないといけなかった。 これは手間なのでStringとInteger/Floatを直接比較できるようにした。
$ cat file 1 foo 2 bar 3 baz $ rf '_ > 1' file 2 bar 3 baz
おわりに
だいぶ実用性が上がってきたと思うのである程度使い方をまとめたドキュメントを作ろうと思っている。 作ろうと思ってzennにページは作った。作っただけ…。 来月Rubyアドカレに参加予定なのでそこまでにはなんとかしたいと思っている。