You are misunderstanding what `put` does.
It does not print the internal representation.
What it does do is turn the value into a `Str` object, then print it with a
trailing newline.
It just so happens that objects will by default return something that looks
like an internal representation when you coerce it to a `Str`.
class Point {
has ($.x, $.y);
}
put Point.new( x => 1, y => 2 ).Str
# Point<94102525076384>
put Point.new( x => 1, y => 2 ).gist
# Point.new(x => 1, y => 2)
put Point.new( x => 1, y => 2 ).raku
# Point.new(x => 1, y => 2)
Unless they have a `.Str` method that returns something more sensible.
class Point {
has ($.x, $.y);
method Str () {
"[$!x,$!y]"
}
}
put Point.new( x => 1, y => 2 ).Str
# [1,2]
put Point.new( x => 1, y => 2 ).gist
# Point.new(x => 1, y => 2)
put Point.new( x => 1, y => 2 ).raku
# Point.new(x => 1, y => 2)
Note that the default of `.gist` is do the same thing as calling `.raku`.
(Many/Most built-in objects have a `.gist` method that returns something
different.)
---
`s///` and `S///` are both intended as working on `Str` objects. So when
you give them something that is not a `Str`, they turn it into a `Str`
first.
Actually all operations that are `Str` operations will turn it into a `Str`
first.
Like `.starts-with`, `.ends-with`, `.chars`, `.codes`, `.index`, `.substr`,
`print`, and `put`
What `say` does, is that instead of calling `.Str` it calls `.gist`
`.gist` is defined as giving enough information for a human to be able to
figure out what object was printed.
(Which is why the default is to return the same thing as `.raku` for
defined objects)
Actually almost all operations are intended for one type of object, and
will coerce to that type.
> say ['a', 'b', 'c'] + %( d => 10, e => 20 )
5
---
Many objects will throw an error if you call `.Str` on them when they are
undefined.
> Bool.Str
Use of uninitialized value of type Bool in string context.
Methods .^name, .raku, .gist, or .say can be used to stringify it to
something meaningful.
in block <unit> at <unknown file> line 1
> Nil.Str
Use of Nil in string context
in block <unit> at <unknown file> line 1
Which means they also throw an error if you try to use one of the methods
intended for `Str` objects on them.
> Bool.substr(0,1)
Use of uninitialized value of type Bool in string context.
Methods .^name, .raku, .gist, or .say can be used to stringify it to
something meaningful.
in block <unit> at <unknown file> line 1
> Bool.^name.substr(0,1)
B
The reason for it generating an error is that generally when you try to
turn an undefined object into a Str, there is likely a bug somewhere.
---
Since `.gist` is for a human, it doesn't matter if the returned value is a
little wrong, so it doesn't fail.
(A human can notice if something is wrong. A program that only does what
you told it to, generally doesn't.)
> Bool.gist
(Bool)
Note that the reason it puts ( and ) around the name of the object is so
that you know that you might have a problem somewhere in your code.
---
Further, Nil is actually the most basic of the Failure objects.
> for Failure.^mro { say .^name }
Failure
Nil
Cool
Any
Mu
If you get a Nil, there is probably some sort of failure somewhere.
> say ( 1, 2, 3, 4 ).first( 'one' )
Nil
Which means that if you try to use a Nil as a Str, there is definitely a
bug in your code.
On Mon, May 18, 2020 at 2:00 AM William Michels via perl6-users <
[email protected]> 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.
>