A discussion earlier today on the chat channel caused me to notice there isn't a way to clone a file object. In particular you can't capture the current stdout file object doing this:
var log-file = (file:open /dev/stdout)
That is because the output capture changes what /dev/stdout refers to and isn't portable.
The original context was an Elvish user who has a function which outputs values they want to capture and log messages to the byte stream they do not want to capture. Here is a stylized example of what they were trying to do using I/O redirection to make it work:
> try { var v = (put 1; echo test >&3) 3>&1 } catch e { }
test
There are problems with using I/O redirection to make that work. First, it's clumsy and hard to discover how to do correctly. Second, they sometimes want the logged output to go to a file so now you have to change all the 3>&1 expressions to 3>log-file. Third, having to do it everywhere you use commands that write log messages to stdout you don't want to capture is very annoying. My proposal is to enhance file:open to accept a literal special source syntax. For example:
> var log-out = (file:open &3) 3>&1
> try { var v = (put 1; echo test >$log-out) } catch e { }
test
That example can also be improved further by defining a log function that captures the log-out variable then using that rather than echo. See also #247.
A discussion earlier today on the chat channel caused me to notice there isn't a way to clone a file object. In particular you can't capture the current stdout file object doing this:
That is because the output capture changes what /dev/stdout refers to and isn't portable.
The original context was an Elvish user who has a function which outputs values they want to capture and log messages to the byte stream they do not want to capture. Here is a stylized example of what they were trying to do using I/O redirection to make it work:
There are problems with using I/O redirection to make that work. First, it's clumsy and hard to discover how to do correctly. Second, they sometimes want the logged output to go to a file so now you have to change all the
3>&1
expressions to3>log-file
. Third, having to do it everywhere you use commands that write log messages to stdout you don't want to capture is very annoying. My proposal is to enhancefile:open
to accept a literal special source syntax. For example:That example can also be improved further by defining a
log
function that captures thelog-out
variable then using that rather thanecho
. See also #247.