I want to override print
to let it output to outstreams other than stdout
. I have two files: m1.sml
and main.sml
in the same directory. I want to override the behavior of print
in both files but it fails to override the print
inside m1.sml
.
m1.sml
structure Demo : sig
val printSomething : string -> unit
end =
struct
fun printSomething s = print s
end
main.sml
use "m1.sml";
fun redirectPrint strm str = TextIO.output (strm, str);
fun testing output =
let
val outStrm = TextIO.openOut output
val print = redirectPrint outStrm
in
(print "This will show up in test.txt\n";
Demo.printSomething "This won't show up in test.txt\n";
TextIO.closeOut outStrm)
end;
testing "test.txt"
Running sml main.sml
will yield
...
[autoloading done]
val redirectPrint = fn : TextIO.outstream -> TextIO.vector -> unit
val testing = fn : string -> unit
this won't show up in test.txt
val it = () : unit
As you have seen in the output, it works for the line
print "This will show up in test.txt\n" (written to test.txt)
but not the next line
Demo.printSomething "This won't show up in test.txt\n"; (printed to stdout)
which just prints to stdout
.
Demo.printSomething
, however, also calls print
. Also, in the current scope where Demo.printSomething
is called, print
was overridden.
I wonder why this happens?
Because identifiers in ML are lexically scoped, as in all modern programming languages.