5

Say we have this module:

unit module outputs;

say "Loaded";

And we load it like this

use v6;

use lib ".";

require "outputs.pm6";

That will print "Loaded" when it's required. Say we want to capture the standard output of that loaded module. We can do that if it's an external process, but there does not seem to be a way for redirecting *OUT to a string or,if that's not possible, to a file. Is that so?

Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
jjmerelo
  • 22,578
  • 8
  • 40
  • 86
  • 1
    Can re-assigning $*OUT/$*ERR dynamic variables help? – Takao Feb 24 '19 at 20:04
  • @takao can we redirect them to a string? I've seen this: https://stackoverflow.com/questions/51407331/how-to-open-a-file-handle-on-a-string-in-perl-6 but I don't really understand that... – jjmerelo Feb 24 '19 at 20:08
  • 1
    See also [If I reassigned OUT in Perl 6, how can I change it back to stdout?](https://stackoverflow.com/q/47318139/2173773) – Håkon Hægland Feb 24 '19 at 20:59

2 Answers2

8

You could try use IO::String:

use v6;
use lib ".";
use IO::String;

my $buffer = IO::String.new;
with $buffer -> $*OUT {
    require "outputs.pm6";
};

say "Finished";
print ~$buffer;

Output:

Finished
Loaded

See also If I reassigned OUT in Perl 6, how can I change it back to stdout?

Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
7

Temporarily reassigning $*OUT so that .print calls append to a string:

my $capture-stdout;

{ 
  my $*OUT = $*OUT but
             role { method print (*@args) { $capture-stdout ~= @args } }

  require "outputs.pm6" # `say` goes via above `print` method 
}

say $capture-stdout; # Loaded
raiph
  • 31,607
  • 3
  • 62
  • 111