久しぶりの更新。前回の更新はこちら。 今回のアップデートは機能の追加とかではなくmrubyのアップデートのみ。 mrubyで以下のPRがマージされたのでアップデートしたという感じ。
この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を使うときの使い方をのせている。 とはいえ、まだ最低限しか書いておらず、内容がスカスカなのでちょっとずつアップデートしていきたい。