Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • But amusing and too easy to write down. Well, my first implementation only did the scalar context case. The second left me hanging between a do-it-all implementation which was not very clear to read and another with auxiliary methods can_oneof and can_someof. The third implementation prevented me of using my @a; for ( @_ ) { ...; push @a, ... }; return @a instead of a proper map. This is it.

    package USUAL;

    sub can_any {
        return wantarray ? goto &can_someof : goto &can_oneof;
    }

    sub can_oneof {
        my $self = shift;
        for ( @_ ) {
            my $can = $self->can($_);
            return $can if $can;
        }
        return;
    }

    sub can_someof {
        my $self = shift;
        return map { $self->can($_) // () } @_;
    }

    1;
    Now insert USUAL into the @ISA array of the package to which belongs the object you are querying about. Yes, I resisted the sin of adding those methods into UNIVERSAL.

    This asymmetrical implementation with a for for the scalar case and a map for the list context made me want a method which did the map job but got rid of the undefs and a scalar equivalent which returned the first defined result value. I reread the docs of List::Util and List::MoreUtils but they did not help me.

    With such methods, the implementation above would look like:

    sub can_oneof {
        my $self = shift;
        return first_defined_value { $self->can($_) } @_;
    }

    sub can_someof {
        my $self = shift;
        return defined_values { $self->can($_) } @_;
    }

    Now that's much more functional-stylish.