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