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

I was reading some older posts today (having come to PM only recently) and came across this snippet from Jeffa:

use strict; my $array = new list qw(foo bar); my $list = new list qw(baz qux); $array += $list; print "@$array\n"; package list; use overload "+=" => sub { push @{$_[0]},@{$_[1]};$_[0] }; sub new { my $class = shift; my $self = [@_]; return bless $self, $class; }

Where he redefined += to mean combine arrays. Now, my question is as follows:

Can I use the same type of programming to change my method calls from object->method() to object.method() ?

Honestly, I'm sure its not bright to do so for reasons of other people maintaining my code ... but it would make *me* happier when I work on purely personal projects.

And of course I could switch the -> to mean concatinate, which in some ways makes sense ....

I don't need to see code samples of 'how to' or anything ... cause I'd rather puzzle it out myself ;-) ... but I'm wondering if its even possible, and if it is, what issues should I be aware of? (Other then non-standard syntax that could mess up other people).

Thank you kind monks for your wisdom, opinions, or bashing. :-)

-Erik

Replies are listed 'Best First'.
Re: Overloading operators: -> to .
by Zaxo (Archbishop) on Sep 26, 2003 at 03:17 UTC

    You could probably overload '.' to mean '->', but '->' is not overloadable. Watch out for interaction with '.='. You may not be able to pass arguments to your methods, since '.' only takes two arguments.

    Why do this? I don't much approve of the purging of C notation from perl 6, and there seems to be no reason at all for it to spill back into perl 5.

    After Compline,
    Zaxo

      You may not be able to pass arguments to your methods, since '.' only takes two arguments.

      Oh, sure you can. You just have to use a trick:

      #!/usr/bin/perl use strict; no warnings; package UNIVERSAL; sub AUTOLOAD { my $method = $UNIVERSAL::AUTOLOAD; $method =~ s/.*:://; return if $method eq "DESTROY"; [$method => @_]; } package DotDotDot; use overload "." => \˙ sub new { bless [] => shift; } sub method { my $self = shift; print "method: @_\n"; } sub dot { my $self = shift; my ($method, @args) = @{+shift}; $self -> $method (@args); } package main; my $obj = DotDotDot -> new; $obj . method (1, 2, 3); __END__ method: 1 2 3

      You may have to fiddle a bit to get inheritance working properly though.

      Abigail

Re: Overloading operators: -> to .
by tilly (Archbishop) on Sep 26, 2003 at 03:18 UTC
    Yes, you can. Since you don't want to have it done for you, just type in perldoc overload into a terminal and learn how to overload the "." operator. It may help you to know that the following works:
    my $meth = "hello"; $foo->$meth(@args); # Calls method 'hello' on $foo with @args
    As noted above, the precedence will be slightly off.

    This will only apply to objects in classes which have your overload set.

    If you want to attempt a more aggressive approach, you can use Filter::Simple to rewrite your code on the fly. That will get the precedence wrong, though you will have far more trouble making your code correct.

    UPDATE: Zaxo is right. Using overload can make the method call happen, but making it pass arguments is another story...

      Filter::Simple by TheDamian on CPAN includes just such a filter as an example, no need to write one.

      --
      I'm not belgian but I play one on TV.

        Classic. Love it.

        I don't know if I should upvote you for knowing something like that ... or downvote you cause you KNEW something like that. :-) Okay, upvote it is.

      Well, great! And thanks. This isn't something I want to do because I *have* to, just something to play around with

      I get some perverse joy from figuring out some things just to figure them out :-)

      the dot notation for methods just seems more elequent to me. When it first appeared in Javascript (the 2nd language I ever learned, the first being Apple Basic in roughly 1985) I was elated.

      So, this is not very serious, but it will give me something to muck around with when I need a bit of distraction here and there. These kinds of things are fun (for me) to work on when I have other problems simmering in the subconcious. :)

      -Erik

Re: Overloading operators: -> to .
by Juerd (Abbot) on Sep 26, 2003 at 09:08 UTC

    Can I use the same type of programming to change my method calls from object->method() to object.method() ?

    See Acme::Dot.

    Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

Re: Overloading operators: -> to .
by jonadab (Parson) on Sep 26, 2003 at 03:11 UTC

    I'm not sure that's possible in Perl5. Overloading += still leaves it as a binary operator and does not change its binding precedence, so the parser doesn't have to care; the only thing that changes is how the operation is performed. Changing method invocation syntax is something else again. If it's possible, it's surely much more involved. As you've probably guessed, simply defining sub . won't do it.

    Now, it WILL be possible in Perl6, but OTOH you won't NEED to do it in Perl6 because Perl6 will come with the method invocation syntax you want out of the box. (When will Perl6 become available? I don't know, but it will be a joyous occasion.)


    $;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b->()}} split//,".rekcah lreP rehtona tsuJ";$\=$ ;->();print$/
Re: Overloading operators: -> to .
by PodMaster (Abbot) on Sep 26, 2003 at 04:45 UTC