Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Perl Best Practice allow having a method name in a string?

Tags:

perl

Is the following code permitted under Perl Best Practice?

my $method_name = q{someMethod};
$self->$method_name();

I know it is suspect style, but does PBP have anything to say about it?

like image 871
null Avatar asked Jul 29 '15 01:07

null


1 Answers

The Perl::Critic module on CPAN has a utility called perlcritic that aims to detect any violations of recommendations from Perl Best Practices. It's not limited just to PBP, though, and there happen to be many policy modules on CPAN that plug into Perl::Critic to provide additional rules. If you prefer not to install Perl::Critic, you can paste your code into perlcritic.com and get feedback at any of the standard Perl Critic levels, gentle through brutal.

Consider the following script:

package Foo;
use strict;
use warnings;

sub new {
    bless {}, shift;
}

sub bar {
    print "Hello\n";
}

package main;
use strict;
use warnings;

my $f = Foo->new;
my $method = 'bar';

$f->$method();

When I run perlcritic myexample.pl --brutal, I do not get any complaints about the means used of invoking the method.

I've read Perl Best Practices, and searched again now for mention of symbolic method calls, and find nothing. That's not to say I haven't missed mention of such constructs, but I can't find them. And Perl::Critic's built-in policies that support PBP seem to concur.

There are actually examples of such in Damian Conway's book, Object Oriented Perl. Of course Damian wrote PBP many years after OOP, and both are old enough by now that better practices have emerged in many cases.

But it's still great to be thinking in terms of what the most maintainable coding styles might be. And if you're concerned that the $object->$method() construct might be difficult to maintain, by all means avoid it unless you have a great reason not to. And in those cases, isolate the use to the narrowest portions of well documented code.

Perhaps a cleaner practice is to obtain a reference to the method rather than a symbol. That can be done with can:

my $method = $f->can('bar');
$f->$method();

The means of invocation looks about the same, but $method contains a code reference which is probably less prone to mistakes. For one thing, can will throw an exception at the time that it is called if there is no bar, rather than an exception being thrown at the time of the actual method call. This is a more defensive approach to programming. And using can instead of just taking a reference to the method, as in my $method = \&Foo::bar has the benefit of playing nice with inheritance, which the hardwired reference doesn't.

like image 151
DavidO Avatar answered Nov 15 '22 11:11

DavidO