How does Perl 6 evaluate truthiness?
Asked Answered
P

6

27

In reading about Perl 6, I see a feature being trumpeted about, where you no longer have to do:

return "0 but true";

...but can instead do:

return 0 but True;

If that's the case, how does truth work in Perl 6? In Perl 5, it was pretty simple: 0, "", and undef are false, everything else is true.

What are the rules in Perl 6 when it comes to boolean context?

Participate answered 24/9, 2008 at 3:30 Comment(3)
in Perl 5 it is common to use '0E0' as a 'zero but true' return valueOmor
I'll give you an upvote for use of the worth "truthiness" in a technical question :)Cap
@PaulDixon: The term is also used in the Ruby community.Honegger
P
3

So to combine what I think to be the best of everyone's answers:

When you evaluate a variable in boolean context, its .true() method gets called. The default .true() method used by an object does a Perl 5-style <0, "", undef> check of the object's value, but when you say "but True" or "but False", this method is overridden with one that doesn't look at the value just returns a constant.

One could conceivable write a true() method which, say, returned true when the value was even and false when it was odd.

Participate answered 24/9, 2008 at 14:28 Comment(0)
R
18

Perl 6 evaluates truth now by asking the object a question instead of looking at its value. The value is not the object. It's something I've liked about other object languages and will be glad to have in Perl: I get to decide how the object responds and can mutate that. As ysth said, you could do that in Perl 5 with overload, but I always feel like I have to wash my hands after doing it that way. :)

If you don't do anything to change that, Perl 6 behaves in the same way as Perl 5 so you get the least amount of surprise.

Royce answered 24/9, 2008 at 7:38 Comment(1)
That'd be more object oriented than Ruby - only false and nil lack truthiness, and there's nothing you can do about it, unless you monkeypatch ! and do !!foo.Honegger
D
11

See Synopsis 12: Roles.

The rules are the same, but the "but" copies the 0 and applies a role to the copy that causes it to be true in boolean context.

You can do the same thing with overload in Perl 5.

Distributive answered 24/9, 2008 at 3:47 Comment(1)
Er, don't you mean "true in a boolean context"?Baughman
G
11

Truthness test just calls the .true method on an object, so the "mix in" operation $stuff but True just (among other things) overrides that method.

This is specified in S02, generally enum types (of which Bool is one) are described in S12.

Guimond answered 24/9, 2008 at 7:44 Comment(0)
D
6

According to O'Reilly's Perl 6 and Parrot Essentials, false is 0, undef, the empty string, and values flagged as false. true is everything else.

Also, Perl 6 has both a primitive boolean type and by having True and False roles that any value can mix in (so you can have a "0 but True" value or a "1 but False" one for example, or a false list containing elements, or a true list that's empty).

See http://www.mail-archive.com/[email protected]/msg09930.html

Diphenylhydantoin answered 24/9, 2008 at 3:42 Comment(1)
That book is ancient and does not represent the current state of the language.Royce
P
3

So to combine what I think to be the best of everyone's answers:

When you evaluate a variable in boolean context, its .true() method gets called. The default .true() method used by an object does a Perl 5-style <0, "", undef> check of the object's value, but when you say "but True" or "but False", this method is overridden with one that doesn't look at the value just returns a constant.

One could conceivable write a true() method which, say, returned true when the value was even and false when it was odd.

Participate answered 24/9, 2008 at 14:28 Comment(0)
D
1

One false value that gets neglected nearly everywhere is "0". I recently made this painful discovery that "0" is false in PERL 5. Gee. A non-empty string that's false. I was really hoping that would change in PERL6, but I guess not.

> if ( "0" ) { say "True" } else { say "False" }
False

The ||= idiom clobbered some strings I really wasn't expecting:

$ perl -e '$x = "0"; $x ||= ""; print ">>$x<<\n";'
>><<
Domiciliary answered 2/5, 2014 at 17:31 Comment(4)
That is why defined-or // is so nice. It's enabled (starting in Perl 5.10) by use 5.010.Apnea
Oops, I just remembered that since defined-or did not conflict with previous syntax, it is enabled by default.Apnea
This answer was written about P6 prior to its first official release in 2015. if ( "0" ) { say "True" } else { say "False" } yields True. The P6 compiler rejects the other line at compile-time. With two changes it compiles and produces what I assume @Domiciliary would consider the correct result: my $x = "0"; $x ||= ""; print ">>$x\<<\n"; # >>0<<.Leclair
@Domiciliary you got your wish. In the Raku REPL: put "0".Bool; returns True, while put "".Bool; returns False. At the command-line, raku -e 'my $x = "0"; $x ||= ""; put ">>"~$x~"<<";' returns >>0<<. HTH.Wsan

© 2022 - 2024 — McMap. All rights reserved.