Re: mocking $*OUT

2017-01-24 Thread Moritz Lenz
Hi Brian,

On 24.01.2017 23:28, Brian Duggan wrote:
> Hi All,
> 
> This code:
> 
>   my $str = '';
>   class Mock {
> method say($arg) { $str ~= $arg }
>   }
>   $*OUT = Mock.new;
>   say 'hi';
> 
> produces:
> 
>   Too many positionals passed; expected 1 argument but got 2
> in block  at out.p6 line 6
> 
> Changing the signature of say doesn't seem to help.
> 
> If I change 'say' to 'print' in Mock, things work
> fine, though I'm having a hard time figuring out why
> the code above doesn't work.  Any ideas?

Because say() is a high-level function that uses the lower-level
$*OUT.print under the hood.

>From rakudo's src/core/io_operators.pm:

multi sub say(Str:D \x) {
my $out := $*OUT;
$out.print(nqp::concat(nqp::unbox_s(x),$out.nl-out));
}

You might be interested in
https://perlgeek.de/blog-en/perl-6/2016-book-testing-say.html :-)

Cheers,
Moritz

-- 
Moritz Lenz
https://deploybook.com/ -- https://perlgeek.de/ -- https://perl6.org/


Re: mocking $*OUT

2017-01-24 Thread Timo Paulssen
You're getting a stack trace that's missing the helpful bits, because
they go through the core setting, and our default backtrace printer
skips those.

You can get the vital information you need by supplying --ll-exception
directly after perl6. It'll show you that calling the sub "say" will
grab $*OUT and call .print on it with what your $*OUT's nl-out method
returns concatenated at the end. The reason why you get the "expected 1
but got 2" is that your $*OUT inherits the default print method from Mu,
which takes no arguments (the 1 argument it does expect is just the
"self", aka the invocant).

BTW, there's two modules in the ecosystem that basically do exactly what
you're trying to do here. They are called IO::String and
IO::Capture::Simple.

Hope that helps!
  - Timo

On 01/24/2017 11:28 PM, Brian Duggan wrote:
> Hi All,
>
> This code:
>
>   my $str = '';
>   class Mock {
> method say($arg) { $str ~= $arg }
>   }
>   $*OUT = Mock.new;
>   say 'hi';
>
> produces:
>
>   Too many positionals passed; expected 1 argument but got 2
> in block  at out.p6 line 6
>
> Changing the signature of say doesn't seem to help.
>
> If I change 'say' to 'print' in Mock, things work
> fine, though I'm having a hard time figuring out why
> the code above doesn't work.  Any ideas?
>
> thanks
> Brian


mocking $*OUT

2017-01-24 Thread Brian Duggan
Hi All,

This code:

  my $str = '';
  class Mock {
method say($arg) { $str ~= $arg }
  }
  $*OUT = Mock.new;
  say 'hi';

produces:

  Too many positionals passed; expected 1 argument but got 2
in block  at out.p6 line 6

Changing the signature of say doesn't seem to help.

If I change 'say' to 'print' in Mock, things work
fine, though I'm having a hard time figuring out why
the code above doesn't work.  Any ideas?

thanks
Brian