Adrien Pierard wrote:
Can you give me a specific situation where you need this? The standard error is seldom used by Gambit's runtime. So all you will be redirecting is your own output which is sent to (current-error-port).
Must be my fault, but I use PP a lot, and as you told me once, it doesn't print on STDOUT (rather on the TTY if I remember correctly, but when I wrote this earlier today, I thought it was STDERR).
Yes pp does print to the "interaction channel" by default (as written in the docs and verified by the following piece of code):
;; file "stderr-and-tty.scm"
(for-each pp (list ##console-port (current-output-port) (current-error-port)))
(display "start..\n" ##console-port)
(parameterize () ;;((current-error-port (current-output-port))) (set! ##console-port (current-error-port)) (display "Hallo") (newline) ;;(pretty-print "pretty-print") (pp "pp-with-explicit-port" (current-error-port)) (pp "pp") 'foo)
; $ gsi stderr-and-tty.scm > out 2>err ; #<input-output-port #2 (console)> ; #<output-port #3 (stdout)> ; #<output-port #4 (stderr)> ; start.. ; "pp" ; $ cat out ; Hallo ; $ cat err ; "pp-with-explicit-port"
As you can see, (set! ##console-port (current-error-port)) didn't have the effect I intended. I can't see a way to change the current console-port (*).
The point of this question, as well as the previous ones, is that I hack vim a bit to let it run interpreters through a proxy, which then remotely prints its results in windows. When I feed it with (begin (display 42) (newline) 'hello)
I have 42 in the STDOUT window, and the symbol hello in the RESULT window. Helps developping/debugging interpreted languages in vim. I then hope that implementors of other interpreted languages (perl, caml) or users will patch their implementations to allow for some with-output-to-file wrapper around the eval function, so that this method to interact with an editor can become generic.
In perl there's no builtin concept of a console port; only through modules which reopen the tty explicitely it gets to the console. The core uses STDERR for warnings. So this is the same as (parameterize ((current-error-port (current-output-port)) ...):
$ perl -we '{ local *STDERR= *STDOUT{IO}; print "Hello\n"; warn "World" } warn "after all"' >out 2>err $ cat out Hello World at -e line 1. $ cat err after all at -e line 1.
(That doesn't take care of C libraries etc. printing to filehandle 2 instead of going through the perl layer to use the STDERR 'variable'. You'd have to close fd 2 and dup 1 to 2 for this, but the same is true (and basically unportable since tied to posix systems) for any other system of course.)
It could also help run interpreters as daemons...
I did write some daemon code some time ago, could dig out code if needed, basically I could get what I wanted; having forgotten how I did it may be a sign that it's not very clear. BTW there's gsi -:d- ; this does what you want, while interestingly ##console-port is still being created and goes to the console, so Gambit *does* have some layer between ##console-port and pp actually, it's just not documented.
Christian.
(*) Well, if you don't mind getting dirty, you could try:
(define (@port-copy! target source) (let ((len (##vector-length target))) (if (= len (##vector-length source)) (begin (force-output target) (force-output source) (let lp ((i 0)) (cond ((< i len) (##vector-set! target i (##vector-ref source i)) (lp (+ i 1)))))) (error "you're wrong"))))
(parameterize () ;;((current-error-port (current-output-port))) (@port-copy! ##console-port (current-error-port)) (display "Hallo") (newline) ;;(pretty-print "pretty-print") (pp "pp-with-explicit-port" (current-error-port)) (pp "pp") 'foo)
; $ gsi stderr-and-tty.scm > out 2>err ; $ cat out ; Hallo ; $ cat err ; "pp" ; ith-explicit-port" ; "pp"
Fine, nothing on the console anymore. Uhm, well, somehow I happened to void the warranty after all ;) (the '"pp-w' part is missing).