NAME

Syntax::Operator::Identical - almost certainly a terrible idea; don't use this

SYNOPSIS

You almost certainly don't want to use this.

However, if despite all my warnings you still want to, then on Perl v5.38 or later:

use v5.38;
use Syntax::Operator::Identical;

my $x = ...;
my $y = ...;

if( $x ≡ $y ) {
   say "x and y are identical";
}

Or via Syntax::Keyword::Match on Perl v5.14 or later:

use v5.14;
use Syntax::Keyword::Match;
use Syntax::Operator::Identical;

my $x = ...;

match($x : ≡) {
   case(undef) { say "The value is not defined" }
   case(123)   { say "The value is identical to 123" }
   case("abc") { say "The value is identical to abc" }
}

DESCRIPTION

This module provides an infix operator that implements an identity test between two values, in a way somewhat similar to the now-deprecated smartmatch (~~) operator, or other similar ideas.

It is probably not a good idea to use this operator; it is written largely as a demonstration on how such an operator could be implemented, as well as to illustrate how fragile it is, in particular around the "is it a string or a number?" part of the logic.

Comparison Logic

This operator acts symmetrically; that is, given any pair of values $x and $y, the result of $x ≡ $y will be the same as $y ≡ $x. It uses the following rules:

  • Definedness

    If both values are undef, the operator yields true. Otherwise, if one value is defined and the other is not, it yields false.

  • Booleans (on Perl v5.36 or later)

    If both values are booleans (as according to builtin::isbool), then the operator returns true or false depending on whether they have the same value. Otherwise, if only one is a boolean then it yields false.

  • References

    If both values are references, the operator yields true or false depending on whether they both refer to the same thing. Otherwise, if only one is a reference it returns false.

  • Non-references

    For any other pairs of values, if either value has a numerical part, then a numerical comparison is made as per the == operator, and if that is false then this operator yields false. Then, if either value has a stringy part, then a string comparison is made as per the eq operator, and if that is false then this operator yields false. Because non-defined and reference values have already been considered at this point, at least one of these tests must necessarily be performed.

    At this point, if there are no other reasons to reject it, the operator yields true.

As a consequence of the boolean rule, on Perl v5.36 or later, real boolean values are not identical to either the numfied or stringified values they would yield.

(5 == 5) == 1;   # is true
(5 == 5) ≡  1;   # is false

(5 == 5) eq "1";   # is true
(5 == 5) ≡  "1";   # is false

As a consequence of the reference rule, references are not identical to a numified or stringified copy of themselves.

my $aref = [];

$aref == 0+$aref;   # is true
$aref ≡  0+$aref;   # is false

$aref eq "$aref";   # is true
$aref ≡  "$aref";   # is false

Also as a consequence of the reference rule, any reference to an object is never considered identical to a plain string or number, even if that object overloads the string or number comparison operators in a way that would consider it to be.

As a consequence of the final non-reference rule, comparisons between a mixture of pure-number and pure-string values will be more strict than either the == or eq operator alone would perform. Both operators must consider the values equal for it to pass.

10 == "10.0";   # is true
10 ≡  "10.0";   # is false, because eq says so

OPERATORS

≡, =:=

my $equal = $lhs ≡ $rhs;
my $equal = $lhs =:= $rhs;

Yields true if the two operands are identical, using the rules defined above. The two different spellings are aliases; the latter is simply an ASCII-safe variant to avoid needing to type the symbol.

≢, !:=

my $unequal = $lhs ≢ $rhs;
my $unequal = $lhs !:= $rhs;

The complement operator to ; yielding true where it would yield false, and vice versa. The two different spellings are aliases; the latter is simply an ASCII-safe variant to avoid needing to type the symbol.

FUNCTIONS

As a convenience, the following functions may be imported which implement the same behaviour as the infix operators, though are accessed via regular function call syntax.

These wrapper functions are implemented using XS::Parse::Infix, and thus have an optimising call-checker attached to them. In most cases, code which calls them should not in fact have the full runtime overhead of a function call because the underlying test operator will get inlined into the calling code at compiletime. In effect, code calling these functions should run with the same performance as code using the infix operators directly.

is_identical

my $equal = is_identical( $lhs, $rhs );

A function version of the operator.

is_not_identical

my $unequal = is_not_identical( $lhs, $rhs );

A function version of the operator.

AUTHOR

Paul Evans <leonerd@leonerd.org.uk>