"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.

Reply via email to