Created
August 20, 2010 14:59
-
-
Save draegtun/540493 to your computer and use it in GitHub Desktop.
Custom infix operators in perl5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
# custom infix operators in perl | |
# see "Infix operators in Python" - http://code.activestate.com/recipes/384122/ | |
# - http://news.ycombinator.com/item?id=1606155 | |
use 5.012; | |
use warnings; | |
{ | |
package Infix; | |
use overload '|' => 'infix'; | |
sub new { | |
my $class = shift; | |
bless { | |
left => undef, | |
code => $_[0], | |
}, $class; | |
} | |
sub left { | |
my $self = shift; | |
bless { | |
%{ $self }, | |
left => $_[0], | |
}, ref $self; | |
} | |
sub infix { | |
my ($self, $arg) = @_; | |
# if right side then evaulate | |
return $self->{code}->( $self->{left}, $arg ) if $self->{left}; | |
# else store left side of infix op | |
$self->left( $arg ); | |
} | |
} | |
my $x = Infix->new( sub { $_[0] * $_[1] }); | |
say 10 |$x| 3; # => 30 | |
say 2 |$x| 1.5; # => 3; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Cool idea, but may I suggest replacing
$x
with a bareword to improve readability:I've also investigated using bracket-like operators, but so far the only one that comes close to working as desired is
This has the advantage that the
<<
and>>
are overloaded separately, so no test is needed to know which is which.(I would have preferred
<MUL>
but the comparison operators<
and>
are non-associative.)Inside the
infix
sub,$_[2]
can be used to determine whether this is a left-side or right-side overloaded operator, which somewhat slightly simplifies the logic.Using a function rather than a method as the constructor allows the use of a
(&)
prototype so thatsub
can be omitted when calling it.I've golfed it down a bit, and used
goto&func
to reduce some of the overhead.which outputs
Another approach would be to have two classes, one for the operator token, which only has a "left"method, and another for the pending left operand, which only has a "right" method.
Whilst this has been fun, it's still just putting lipstick on a pig; we really need proper operator definitions, like in Raku.