Search code examples
perlperl-critic

perlcritic: "require" statement with library name as string Use a bareword instead


Perlcritic complains about the following line of code:

require "bin/menu.pl";

"require" statement with library name as string Use a bareword instead.

However if I change it to a bare word:

require bin/menu.pl

I get an illegal division by zero error.

To reproduce just run perlcritic on any perl script that 'requires' another perl script.

The docs for require suggest using a string: https://perldoc.perl.org/functions/require Is this a bug in perlcritic?


Solution

  • In this case you should ignore Perl::Critic. It's perfectly fine to load a library with require like you are doing. It's not popular anymore, but that is the original idea of require. Tell Perl::Critic to ignore that line:

    require 'some/path/some_library.pl'; ## nocritic
    

    Don't use Perl::Critic to tell you what to do. Use it as a tool to look at things that might need attention, then make a decision based on the context of your task.

    As people have noted, require will only execute the code the first time around. If that's what you want (and it probably is because that's been working up to now), leave the code as is.

    Some people have suggested turning this into a module, in which case you probably just end up exporting all the subroutines anyway. You end up in the same place with extra steps. That might be fine when you're looking for something to do and can't find anything more pressing.


    @ikegami's point is in general correct, and my answer is only appropriate in the situation presented. require tracks that files it has already processed so it does not reprocess it again. If the code in the library defines its own namespace, anything in the program can access the subs (or whatever) it defines through that namespace.

    If it does not define a namespace, whatever it does ends up in whatever the default namespace was when it was executed. That can pollute that namespace and you might not be able to know where those definitions ended up. Generally, small programs use main:: and never leave it, and everything ends up in main:: so it all works out.

    If the library executed code when required (so, stuff outside of sub definitions), you have to decide if you need that to happen multiple times. That would be a weird situation and probably raises eyebrows, but do would handle that.

    But, more likely, people want those things to happen only once, so require handles that. Say that you set a global variable in this library, but go on to modify it elsewhere in the program. Bad practice, but that's how the world is. If you run the library code again, your variable is silently reset.

    If you were starting fresh, do what @ikegami says. If you are supporting code that been running fine, just let it do its thing even if it is wrong. Even known bugs are sometimes left better undisturbed until you have the proper amount of time to ensure the fix isn't worse. It always seems like it should work if you just make this one change, and then it ends up all broken in different ways that nobody expects. I've rescued many situations where someone decided to change something working because Perl::Critic told them to, and now they had 99 problems. (Heh, don't set default regex flags!)

    At some point you might have time to clean up that stuff, but more likely there is other work that should take up your time. I should have made that more clear in my original answer.