Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Overloading assignment

by v_o_i_d (Novice)
on Oct 26, 2004 at 05:12 UTC ( [id://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,
    Zaxo

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:
    #---Sample.pm--- 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..
    #----code.pl---- 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 code.pl line 28. Argument " bishop" isn't numeric in addition (+) at code.pl 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,
      Zaxo

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

    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?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (3)
As of 2024-04-20 02:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found