"say $x" is essentially equivalent to "put $x.gist".
Since Nil is undefined (roughly equivalent to a type object), Nil.gist has a
string value of "Nil" and can be printed. However, attempting to convert Nil
directly into a Str throws an error because that's attempting to stringify an
undefined object.
You can see this with the following:
$ rakudo
To exit type 'exit' or '^D'
> say Nil
Nil
> put Nil
Use of Nil in string context
in block <unit> at <unknown file> line 1
> say Nil.Str
Use of Nil in string context
in block <unit> at <unknown file> line 1
> put Nil.gist
Nil
So, the difference in your example is that when the result of s/.../.../ is Nil
(representing a failed Match), C<say> calls .gist on Nil which produces a
printable string, while C<put> attempts to stringify the Nil object directly
and that throws an error.
Pm
On Sun, May 17, 2020 at 11:59:18PM -0700, William Michels via perl6-users wrote:
> Hello,
>
> I'm interested in knowing the differences between the return values
> when "say" is used compared to "put". My understanding is that "put"
> returns Raku's internal representation of a value held by a variable,
> while "say" is merely "put" with the .gist method called on it (a
> "human readable", often-abbreviated return value).
>
> Below I do "S///" (non-destructive) and "s///" (destructive) text
> replacement on a three line text file in bash line [1]. In bash line
> [2], the full substituted text file is correctly returned; in bash
> line [3] using "say" only the $/ match string is returned. So far so
> good. However, a virtually-identical call in bash line [4] using "put"
> instead of "say" returns an error for the first line of the target
> text file: "Use of Nil in string context in block at -e line 1".
>
> [1] homedir$ cat demo1.txt
> this is a test,
> I love Unix,
> I like Linux too,
>
> [2] homedir$ perl6 -ne 'say S/love|like/admire/;' demo1.txt
> this is a test,
> I admire Unix,
> I admire Linux too,
>
> [3] homedir$ perl6 -ne 'say s/love|like/admire/;' demo1.txt
> Nil
> 「love」
> 「like」
>
> [4] homedir$ perl6 -ne 'put s/love|like/admire/;' demo1.txt
> Use of Nil in string context
> in block at -e line 1
>
> love
> like
>
> [5] homedir$
>
> I'm really trying to understand this error message: doesn't Raku know
> that this is a text replacement operation? How can a 'Nil' be
> correctly represented when called by "say", but throw an error when
> called by "put"? If the value is absent at the Raku representational
> level and throws an error, wouldn't it be reasonable to assume that
> the same case would hold for "say"? And finally, does this "say / put"
> difference mean that some textual information will be lost from return
> values (because "say" will have to be used instead of "put" to avoid
> errorring-out)?
>
> Any enlightenment appreciated,
>
> TIA, Bill.