gopher-lua icon indicating copy to clipboard operation
gopher-lua copied to clipboard

Allow redirecting stdout with io.write

Open drognisep opened this issue 4 years ago • 10 comments

  • [x] GopherLua is a Lua5.1 implementation. You should be familiar with Lua programming language. Have you read Lua 5.1 reference manual carefully?
  • [x] GopherLua is a Lua5.1 implementation. In Lua, to keep it simple, it is more important to remove functionalities rather than to add functionalities unlike other languages . If you are going to introduce some new cool functionalities into the GopherLua code base and the functionalities can be implemented by existing APIs, It should be implemented as a library.

Please answer the following before submitting your issue:

  1. What version of GopherLua are you using? : github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9
  2. What version of Go are you using? : go version go1.17.1 windows/amd64
  3. What operating system and processor architecture are you using? : Windows 10 20H2 19042.1320, Intel(R) Core(TM) i7-10875H CPU @ 2.30GHz
  4. What did you do? : Redirected os.Stdout to the write side of an os.Pipe
  5. What did you expect to see? : I expected print and io.write to print to the redirected stream.
  6. What did you see instead? : print prints to os.Stdout (using fmt.Print), but io.write does not. I would expect these functions to be consistent in how they select their output stream.

I'm trying to wrap gopher-lua into a graphical script runner with Fyne along with an output panel to show the result of the script. I've observed that Lua-side print writes to os.Stdout no problem because it uses fmt.Print, but io.write instead writes to the application's original stdout stream regardless of the value of os.Stdout. To support this functionality it would be nice if both print and io.write (and other I/O functions) used Go-side os.Stdout, os.Stderr, os.Stdin streams so they can be easily redirected to the graphical component. The alternative is generating a new executable and running it in a new process to redirect streams every time the user changes the script in the UI, which would be a huge pain.

drognisep avatar Nov 05 '21 22:11 drognisep

#335 use overrid global function to redirect to anything you like.

ZenLiuCN avatar Nov 15 '21 17:11 ZenLiuCN

@ZenLiuCN Of course I can override if need be. Shouldn't it be consistent in the base implementation? What is the benefit of not having both reference the same streams in the same way?

I think linking both of them to Go's os.* streams would make this use-case simpler for people and make the change to redirect much more consistent with gopher expectations without having force people to dig into the internals and override global functions. Is there something I'm missing?

drognisep avatar Nov 16 '21 16:11 drognisep

@ZenLiuCN Of course I can override if need be. Shouldn't it be consistent in the base implementation? What is the benefit of not having both reference the same streams in the same way?

I think linking both of them to Go's os.* streams would make this use-case simpler for people and make the change to redirect much more consistent with gopher expectations without having force people to dig into the internals and override global functions. Is there something I'm missing?

so why not just try to make a pull request?

ZenLiuCN avatar Nov 16 '21 17:11 ZenLiuCN

Maybe I misunderstood. Is this not being maintained anymore?

drognisep avatar Nov 16 '21 17:11 drognisep

I do not know. just been use this lib current days. ^_^

ZenLiuCN avatar Nov 16 '21 18:11 ZenLiuCN

Ah, okay. I don't have the time to prop up a lib with no maintainer. Thanks for the tip though @ZenLiuCN. :D

drognisep avatar Nov 16 '21 22:11 drognisep

I have a very similar issue: I'm running Lua scripts as part of a web server and want to capture the output to send it to a webpage (using SSE, WebSockets, or anything like that). The 'obvious' choice would be simply to redirect Lua's stdout to some Go stream and push that out to the HTTP stream (probably it may be even simpler than the code I'm writing; I'm adding some error checking, etc.). Sadly, GopherLua seems to simply send everything from print() to stdout, with no way to grab it. Is that so? I'm still looking through all the posted issues here to see if there is a way using the current codebase...

Oh, sure, I could simply override print(), but, in that case, I'd have to deal with all the syntactic sugar from Lua's own print(). I might more easily create my own pseudoprint() which just sends output... uh, somewhere where I can grab it (note that I'm using luar to make things much simpler, so I might not be able to delve as deep as I wish).

GwynethLlewelyn avatar Mar 06 '22 19:03 GwynethLlewelyn

Update: On another issue here, I've found something that would work in my case: https://github.com/xyproto/algernon/blob/34d3806bfa890e7f6296cc400e8fd51951cdc926/basic.go#L67

GwynethLlewelyn avatar Mar 06 '22 20:03 GwynethLlewelyn

Im maintaining a fork of this project since a few years, where I added the feature to optionally redirect stdin, stdout and stderr. All calls (even internal usages of stdout/stderr) are using those instead.

The streams can be overwritten in lua.Options, where I added the following fields:

// Options is a configuration that is used to create a new LState.
type Options struct {
	// <other fields>

	// Stdin stream. Defaults to os.Stdin
	Stdin io.ReadCloser
	// Stdout stream. Defaults to os.Stdout
	Stdout io.WriteCloser
	// Stderr stream. Defaults to os.Stderr
	Stderr io.WriteCloser
}

I'm using this fork in production for a few years now without any issues. If there's any interest, I'd be glad to provide a PR.

maja42 avatar Jun 14 '22 13:06 maja42

Speaking strictly as an end-user of gopher-lua, I'd love to have your PR! Hopefully, @yuin is able to review it and add it to the main branch...

GwynethLlewelyn avatar Jun 19 '22 19:06 GwynethLlewelyn