pilcrow
pilcrow

Reputation: 58681

Suppress void context warning for overloaded operator

Is there a means to suppress specific warnings in the caller for an overloaded operator?

Background: I'm looking at a module that overloads <= and >= to implement a sort of declarative domain specific alnguage. Whether or not that's a good idea aside, these operators throw "Useless use in void context" warnings when used in a void context. Something like:

package Boundary;

use strict;
use overload ('<=' => \&set_min, '>=' => \&set_max);

sub new     { my ($class, $min, $max) = @_; bless [ $min, $max ], $class; }
sub set_min { my $self = shift; $self->[0] = shift; }
sub set_max { my $self = shift; $self->[1] = shift; }

package main;

# user code
use warnings;

my $bound = Boundary->new();
$bound >=  1;  # Useless use of numeric ge (>=) in void context at ...
$bound <= 10;  # Useless use of numeric le (>=) in void context at ...

Is there a way to suppress the warnings just for the overloaded calls, without the caller having to explicitly disable 'void' warnings?

Upvotes: 4

Views: 501

Answers (3)

Borodin
Borodin

Reputation: 126742

I suggest you overload the <<= and >>= operators instead as the compiler expects them to be used for their side-effects. Alternatively you may prefer -= and +=.

You would need to return $self from the overload subroutines, as the LHS of an operator like this is set to the return value and you don't want it to change.

Upvotes: 2

msztolcman
msztolcman

Reputation: 447

There is no possibility, I guess. The only solutions I have is:

  • change your API
  • live with this warnings (you can filter them via __WARN__ pseudo signal handler)
  • use weird syntax:

    $bound >= 1 or 0;

I think the first choice is best ;)

Upvotes: 1

ikegami
ikegami

Reputation: 386406

Perl expects that you preserve existing semantics when you overload an operator. e.g. It sometimes optimises negation away. You're playing with fire.

$ perl -MO=Concise,-exec -e'$y = !$x;'
1  <0> enter
2  <;> nextstate(main 1 -e:1) v:{
3  <$> gvsv(*x) s
4  <1> not sK/1                    <--- "not" operator
5  <$> gvsv(*y) s
6  <2> sassign vKS/2
7  <@> leave[1 ref] vKP/REFC
-e syntax OK

$ perl -MO=Concise,-exec -e'if (!$x) { f() }'
1  <0> enter 
2  <;> nextstate(main 3 -e:1) v:{
3  <$> gvsv(*x) s
4  <|> or(other->5) vK/1           <--- No "not" operator
5      <0> pushmark s
6      <$> gv(*f) s/EARLYCV
7      <1> entersub[t1] vKS/TARG,1
8  <@> leave[1 ref] vKP/REFC
-e syntax OK

Upvotes: 3

Related Questions