Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

Overloading assignment

by v_o_i_d (Novice)
on Oct 26, 2004 at 05:12 UTC ( #402464=perlquestion: print w/replies, xml ) Need Help??

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

Hi i'm new here..and am humbly seeking wisdom from those within...

Can anyone tell me if it is possible to overload operators such as addition(+) AND overload assignment as well. i have searched but found no hard answer-not even vague suggestions.

Specifically, ...

In my own experiments I have tried to overload and tiescalar in the same class, but FETCH seems to interfere and the tie function causes a loss of context because the overloded operators never work after this. Using the returned object from tie() still works however but then you have 2 individual variables each with separate functionality.
...Any ideas on how to make custom assignment code like FETCH AND overload operators work in the same class?
Thanks perl monks!

*UPDATE* Just so you know I posted some code in a new reply!

Replies are listed 'Best First'.
Re: Overloading assignment
by Zaxo (Archbishop) on Oct 26, 2004 at 05:29 UTC

    Assignment can't really be overloaded. If you say use overload '=' . . .;, you are arranging for a copy constructor for use by mutators like ++, += and so on.

    To intercept and modify the workings of the assignment operator, you need to use a tied interface, as you seem to be getting at. If you are having trouble with that code, please show what you've tried and what errors you get.

    After Compline,

Re: Overloading assignment
by v_o_i_d (Novice) on Oct 26, 2004 at 06:39 UTC
    I have done what you said. Here is the code...
    Simple class example for demonstration purposes: package Sample; use warnings; use strict; use overload( '+' => \&add, fallback => 1, ); sub TIESCALAR { my $class = shift; my $self = { data => [@_], }; bless( $self, $class ); return $self; } sub add { $_ .= $_[1] foreach( @{$_[0]->{data}} ); } sub STORE { @{$_[0]->{data}} = (ref( $_[1] ) eq 'ARRAY') ? @{$_[1]}: ($_[1]); } sub FETCH { return $_[0]; } 1; #---------------
    Next is the program.. use warnings; use strict; use Sample; my $var1; my $var2 = tie( $var1, 'Sample', 'black', 'white' ); # The assigment test... #$var1 = 'green'; #$var2 = ['green','red']; # The overload test... #$var1 + ' bishop'; #$var2 + ' bishop'; #print ref($var2),"\n"; print join( "\n", @{$var2->{data}} ); exit 0; #---------------
    Compiler warnings/errors: (addition operation on the tie() variable $var1)
    Useless use of addition (+) in void context at line 28. Argument " bishop" isn't numeric in addition (+) at line 28.
    * The returned variable $var2 however, will cause the 1st warning but successfully calls the 'addition' Sample::add.

    The opposite works with assignment:
    $var2 = ['green','red'] destroys the class instance of Sample and becomes an array reference. $var1 = ['green','red'] works as it should because of tie()!

    Both operations don't work on the same variable, $var1 can't do the addition + and $var2 can't do the assignment!

      Both your tie class and the overloaded add are not quite correct.

      The FETCH routine does not return a scalar of the expected kind. You have it returning a reference to the underlying hash, rather than some scalar data stored in it.

      An overridden operator like '+' is written like a constructor. It should take data from its arguments and return a new object of the correct type constructed from the result. What you have written for add is a mutator which behaves more like '.=' than '+'. It is a good idea to make sure overridden operators are as much like the builtins as possible.

      I'm not sure there is a way to make a tied variable honor the underlying classes' operator overrides. I wasn't aware of that, but my attempts to make it happen have failed.

      After Compline,

Re: Overloading assignment
by v_o_i_d (Novice) on Nov 25, 2004 at 05:57 UTC

    Combining use overload and tie() can be done, but it requires overloading one of the scalar dereference operators (or any of the others). ie. ${}  @{}  %{} etc.

    The basic idea is that you tie() self inbetween the dereferencing operation.

    The only drawback is you must dereference to tie() the object (in ribbons ;). You will use it like this:

    $var + 1; # use overload '+'... $$var = 'custom STORE'; # STORE() called...
    Cheers buds!

    Disclaimer: Use at your own risk. May not work for you like it did for me.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://402464]
Approved by atcroft
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (3)
As of 2021-09-20 14:37 GMT
Find Nodes?
    Voting Booth?

    No recent polls found