ぶていのログでぶログ

思い出したが吉日

rfコマンドv1.18.1をリリースした / rfコマンドハンドブックの公開

久しぶりの更新。前回の更新はこちら。 今回のアップデートは機能の追加とかではなくmrubyのアップデートのみ。 mrubyで以下のPRがマージされたのでアップデートしたという感じ。

Fixed Binding#eval that failed to assign to the same variable by dearblue · Pull Request #6275 · mruby/mruby

このPRでは、Binding#evalにおいて同名の変数が同一としてカウントされずローカル変数の定義数を超えてしまうという問題を解決している。 具体例でいうと、以下では変数iを1度だけ初期化し、その後1000回iをインクリメンタルしているが、too many local variables for bindingとなってしまう。

b=binding
b.eval("i||=0")

1000.times do
  b.eval("i+=1");
end
#=> trace (most recent call last):
#=>        [2] -e:1
#=>        [1] -e:1
#=> -e:1:in eval: too many local variables for binding (mruby limitation) (RuntimeError)

これをなぜ発見したかというとrfで集計しようと以下のようなコマンドを実行したときにこの問題が起こっていたのであった。

# 例として1から500までの連続した数値を出力
$ seq 1 500 > inputs.txt

# すべてを合算する
$ rf -q 's||=0; s+=_1; at_exit{puts s}' inputs.txt
Error: too many local variables for binding (mruby limitation)

sをグローバル変数にすることで回避できるのだが、type数が増えるのとawkのように変数名に $をつけたくなかったのでなんとかしようとしていた。 結局解決策がわからずmrubyの仕様なのかと思いdiscussionで相談したところ、バグであったことがわかり、その後爆速で修正されたのであった。最高!

rfのv1.8.1では当然前述の合算は正常に行える。

$ rf -q 's||=0; s+=_1; at_exit{puts s}' inputs.txt
125250

rfコマンドハンドブックを公開した

rfの利用者を増やしたいのだが、実環境でどのように使えるか?みたいなのが伝わりづらいと思ったので、ハンドブックという形で私が普段rfを使うときの使い方をのせている。 とはいえ、まだ最低限しか書いておらず、内容がスカスカなのでちょっとずつアップデートしていきたい。

zenn.dev