Reputation: 1135
I was trying to overload the logical or
operator for a custom class, but it doesn't seem to work. This is what I do:
class A { has $.a }
multi sub infix:<or> (A $a, A $b) {
"works!({$a.a}, {$b.a})"
}
say A.new(:1a) or A.new(:2a);
I'm expecting to get works!(1, 2)
as output, but instead I get A.new(a => 1)
, which is the result of the standard or
operator.
Other operators (except for and
and xor
), seem to work for me:
class A { has $.a }
multi sub infix:<anything-else> (A $a, A $b) {
"works!({$a.a}, {$b.a})"
}
say A.new(:1a) anything-else A.new(:2a);
results in works!(1, 2)
.
Am I doing something wrong or is there just no way to overload the standard or
,and
,xor
operators?
Upvotes: 15
Views: 184
Reputation: 29454
Only operators that compile into a subroutine call may be overloaded. Since subroutine calls have their arguments evaluated prior to the call being made, those operators that require delayed evaluation of one of their operands are handled as special forms in the compiler.
The logical operators, like and
, or
, &&
, and ||
, are specified as only evaluating their second operand depending on the truthiness of their first operand, and so cannot be compiled into subroutine calls.
Even if they were to compile into a subroutine call that thunked the second operand, a multiple dispatch as written in the question would still not be possible on the type of the second argument, since the semantics of these operators mean we can't evaluate it right away, but that in turn means we can't find its type in order to do the dispatch.
Upvotes: 15