Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to do some overloading. Stringification, dereferencing and some others are working fine, but I have a problem with ">>", "<<", ">", "<" so far... overloading is successfull, but it generates a warning. Code is below:
package Foo; use strict; use overload '>>' => 'right_shift'; sub new {bless {}, __PACKAGE__} sub right_shift { print "OK!\n"} 1;
#!/usr/bin/perl -w use strict; use Foo; my $foo = Foo->new; "test" >> $foo;
this generates the following output:
Useless use of right bitshift (>>) in void context at foo.pl line 5. OK!
perl: ActivePerl 5.8.6.811 os: windows xp pro
am I doing something wrong, or this warning is normal?

Replies are listed 'Best First'.
Re: overloading ">>" generates warning?
by Joost (Canon) on Aug 07, 2005 at 18:46 UTC
    You could argue that your use of overloading is too confusing.

    That warning is generated at compile-time, and is correct for non-overloaded invocants (>> returns a new value, and doesn't modify its parameters), so I'd say the behaviour is expected, but annoying in this case.

    You can disable the warning by using

    no warnings 'void';

    By the way, stringification gives you the same warning in similar cicumstances:

    #!/usr/bin/perl -w use strict; my $foo = Foo->new; "$foo"; package Foo; use strict; use overload '""' => 'stringy'; sub new {bless {}, __PACKAGE__} sub stringy { print "OK!\n"}

    Useless use of string in void context at test.pl line 4. OK!

Re: overloading ">>" generates warning?
by tlm (Prior) on Aug 07, 2005 at 21:26 UTC

    The warning has nothing to do with overloading. You can reproduce it with the core >>:

    % perl -we '$foo = 1; 3 >> $foo' Useless use of right bitshift (>>) in void context at -e line 1.
    As the warning says, you are using the operator in a void context. If you use it in a non-void context the error goes away; this is true even for your overloaded operator.

    The root of the problem is that you are trying to turn an operator that normally has no side effects into one that does (and, apparently it is only the side effects of this new operator that you're interested in). (In particular, note that the core >> does not modify its LHS.)

    I suppose you can silence the warnings with something like

    () = "test" >> $foo;

    the lowliest monk

      what I'm trying to do is a file IO similar to IO::All' s, but only for files. It also uses this syntax, but don't generate any warnings. I didn't get how Ingy did that thing without a warning :(

        Use the source, Luke! Have you looked at the source code? :-)

        my $old_warn_handler = $SIG{__WARN__}; $SIG{__WARN__} = sub { if ($_[0] !~ /^Useless use of .+ \(.+\) in void context/) { goto &$old_warn_handler if $old_warn_handler; warn(@_); } };

        It looks like he basically turned off that warning globally.

        the lowliest monk