標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

内蔵Luaで実行する際、@ で始まる行を無視するよう修正した

nyagos 4.3 で、バッチファイルに Lua を組み込んで実行する際、内蔵Lua が 5.3 から 5.1 になったため、ラベルの文法がなくなって

@setlocal & set "ARGS=%*" & nyagos.exe --norc  -e "_,_,b=io.input([[%~f0]]):read('*l','*l','*a');assert(loadstring('\n'..b,[[%~f0]]))()"
@endlocal & exit /b %ERRORLEVEL%

とかヘッダに書かなくてはいけなくなって、たいへんになった…とに書いた。 でも、ホストアプリケーションを自分で書いているんだから、このくらい何とか出来そうなもんだ。

ということで、何とかした:

@nyagos --norc --lua-file "%~f0" %*
@exit /b %ERRORLEVEL%

for key,val in pairs(arg) do
    print(key,val)
end

単に読み出す時に @ で始まる行をカットするようにしただけ。 これを実現するのが以下の関数

func DoFileExceptForAtmarkLines(L *lua.LState, fname string) error {
    fd, err := os.Open(fname)
    if err != nil {
        return err
    }
    reader, writer := io.Pipe()
    go func() {
        scan := bufio.NewScanner(fd)
        for scan.Scan() {
            line := scan.Text()
            if len(line) > 0 && line[0] == '@' {
                line = ""
            }
            fmt.Fprintln(writer, line)
        }
        writer.Close()
        fd.Close()
    }()
    f, err := L.Load(reader, fname)
    reader.Close()
    if err != nil {
        return err
    }
    L.Push(f)
    return L.PCall(0, 0, nil)
}

GopherLua には文字列を実行する LoadString , ファイルを実行する LoadFile の他に、io.Reader を取る Load があるので、それに ioPipe のパイプラインの Reader 側を渡しているわけだ。こんなカジュアルに goroutine を作ってもいいのかなぁとつい考えてしまうが、全部を読みだして、string.Builder で文字列化してから、string.Reader を渡すよりはマシか。もっとコスト低い方法はないかな…