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 を渡すよりはマシか。もっとコスト低い方法はないかな…