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

Is there a way to reliably call operators such as eq, ne, etc. on an object which you know has those operators overloaded? However, I don't want to make assumptions about the class of the object.

Here's an example:

sub create_selector { my ($spec) = @_; my $selector; if ($spec =~ m/^=(.*)/) { $selector = sub { $_[0]->version eq $1 } } elsif ($spec =~ m/!=(.*)/) { $selector = sub { $_[0]->version ne $1 } } elsif ($spec =~ m/>(.*)/) { $selector = sub { $_[0]->version gt $1 } } $selector; } my $selector = create_selector("=6.2"); ... my @selected_dists = grep { $selector->{$_} } @list_of_dists;
The idea is that I could write create_selector like this:
sub create_selector { my ($spec) = @_; my $selector; if ($spec =~ m/^(=|!=|<|>)(.*)/) { my $op = $1; my $method = ...translate $op to a method name... $selector = sub { $_[0]->version->$method($2) } } }
That is, I want to be able to perform the translation of $op to a method name in a way which will work for whatever object I'll be applying it to.

Replies are listed 'Best First'.
Re: calling overloaded comparison operators as method calls?
by morgon (Priest) on Jul 05, 2009 at 20:32 UTC
    I am not sure if I understand your problem.

    If you make your selector like this:

    my $selector = sub { $_[0] eq $whatever };
    Then you can call it with any object as $selector->($object) (parentheses - not curly braces to call it!) and it will either use the built-in eq or the overloaded version. As far as I understand you that is what you want which is why I probably don't understand you...

    But as an aside you can get a reference to the overloading method with overload::Method, so if you really wanted you could to something like (for the "eq"-case)

    my $selector = sub { my($obj)=@_; my $code_ref = overload::Method($obj, "eq"); if($code_ref) { # $obj overloads "eq" # call the overloading-implementation return $code_ref->($obj, $whatever); else { # no overloading -do something else return $obj eq $whatever; } };
      What I want is the overload::Method function. That way I don't have to write separate conditionals for each operation.

      Thanks!

        btw: All of that is covered in the manpage (perldoc overload) - rtfm :-)