B::Lint(3pm)

πŸ“¦
version 1.22 Β· 4 versions
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

πŸ’– B::Lint β€” bestie, it's the Perl linter πŸ’–

okay so real talk, this is B::Lint from the User Contributed Perl Documentation, and it's about to become your new hyperfixation. sit down, hydrate, let's go 🫢


✨ NAME ✨

B::Lint β€” Perl lint. that's it. that's the name. iconic, brief, no notes πŸ’…


🌸 SYNOPSIS 🌸

perl -MO=Lint[,OPTIONS] foo.pl

that's the whole vibe. one line. she's efficient.


πŸ¦‹ DESCRIPTION πŸ¦‹

so B::Lint is basically the -w option of perl but ✨extended✨, like when your fave artist drops the deluxe version of the album. it's named after the program lint, which does the same kind of thing but for C programs. so yeah, she's named after an icon. legacy. πŸ’œ


πŸŽ€ OPTIONS AND LINT CHECKS πŸŽ€

okay so here's the important part, listen up bestie πŸ“’

Option words are separated by commas, not whitespace (not me getting that wrong the first time 😭), and they follow the usual conventions of compiler backend options. After any options (the ones with a leading -) come the lint check arguments. Each such argument (apart from the special all and none options) is a word representing one possible lint check (turning on that check) or is no-foo (turning off that check). Before processing the check arguments, a standard list of checks is turned on. Later options override earlier ones. the way that options stack is very main character energy fr fr.

Available options, let's get into it:

  • magic-diamond β€” she yells at you whenever the magic <> readline gets used. internally it uses perl's two-argument open, which itself treats filenames with special characters specially. so a file with a cute lil spicy name could have unexpected effects when reading. not cute. πŸ’€
% touch 'rm *|'
% perl -pe 1

the above creates a file named rm *|. when perl opens it with <> it actually executes the shell program rm *. that makes <> dangerous to use carelessly. no cap, that's a whole villain arc.

  • context β€” warns whenever an array is used in an implicit scalar context. for example, both of these lines:
$foo = length(@bar);
$foo = @bar;

will elicit a warning. using an explicit scalar() silences the warning, like:

$foo = scalar(@bar);
  • implicit-read and implicit-write β€” these produce a warning whenever an operation implicitly reads or (respectively) writes to one of Perl's special variables. for example, implicit-read will warn about this:
/foo/;

and implicit-write will warn about this:

s/foo/bar/;

Both implicit-read and implicit-write warn about this:

for (@a) { ... }
  • bare-subs β€” warns whenever a bareword is implicitly quoted, but is also the name of a subroutine in the current package. typical mistakes that she will trap:
use constant foo => 'bar';
@a = ( foo => 1 );
$b{foo} = 2;

neither of these will do what a naive user would expect. bestie, it's giving chaos 😭

Notice: Perl 5.22.0 does not report "foo" in $b{foo} as BARE token anymore. Therefore B::Lint test is not reliable here. See CPAN RT#101115 https://rt.cpan.org/Public/Bug/Display.html?id=101115. πŸ’€
  • dollar-underscore β€” warns whenever $_ is used either explicitly anywhere, or as the implicit argument of a print statement. she's watching $_ like a hawk πŸ¦…
  • private-names β€” warns on each use of any variable, subroutine or method name that lives in a non-current package but begins with an underscore (_). Warnings aren't issued for the special case of the single character name _ by itself (e.g. $_ and @_). so the lone underscore gets a pass, she's chill like that πŸ™ˆ
  • undefined-subs β€” warns whenever an undefined subroutine is invoked. This option will only catch explicitly invoked subroutines such as foo() and not indirect invocations such as &$subref() or $obj->meth(). Note that some programs or modules delay definition of subs until runtime by means of the AUTOLOAD mechanism. sneaky, sneaky πŸ‘‘
  • regexp-variables β€” warns whenever one of the regexp variables $`, $& or $' is used. Any occurrence of any of these variables in your program can slow your whole program down. See perlre for details. like, the entire thing. slow. don't do it πŸ”₯
  • all β€” Turn all warnings on. periodt ✨
  • none β€” Turn all warnings off. silence. peace. 🌈

πŸ’œ NON LINT-CHECK OPTIONS πŸ’œ

  • -u Package β€” Normally, Lint only checks the main code of the program together with all subs defined in package main. The -u option lets you include other package names whose subs are then checked by Lint. it's giving "let her into the group chat" πŸ’…

🧚 EXTENDING LINT 🧚

Lint can be extended by with plugins (yes bestie, she's got a plugin ecosystem, she's that girl). Lint uses Module::Pluggable to find available plugins. Plugins are expected but not required to inform Lint of which checks they are adding.

The B::Lint->register_plugin( MyPlugin => \@new_checks ) method adds the list of @new_checks to the list of valid checks. If your module wasn't loaded by Module::Pluggable then your class name is added to the list of plugins.

You must create a match( \%checks ) method in your plugin class or one of its parents. It will be called on every op as a regular method call with a hash ref of checks as its parameter.

The class methods B::Lint->file and B::Lint->line contain the current filename and line number. so useful, so slay 🫢

package Sample;
use B::Lint;
B::Lint->register_plugin( Sample => [ 'good_taste' ] );

sub match {
    my ( $op, $checks_href ) = shift @_;
    if ( $checks_href->{good_taste} ) {
        ...
    }
}

⭐ TODO ⭐

  • while(<FH>) stomps $_
  • strict oo
  • unchecked system calls
  • more tests, validate against older perls

the to-do list is a mood honestly πŸŽ€


πŸ’€ BUGS πŸ’€

This is only a very preliminary version. she's a work in progress, be gentle 😭


πŸ‘‘ AUTHOR πŸ‘‘

Malcolm Beattie, mbeattie@sable.ox.ac.uk.


🌸 ACKNOWLEDGEMENTS 🌸

Sebastien Aperghis-Tramoni - bug fixes


and that's the whole page bestie πŸ’– this was documented for perl v5.36.0, dated 2022-11-19, and it's filed under B::Lint(3pm) β€” go forth, lint responsibly, and remember: commas not whitespace πŸ¦‹βœ¨

πŸ“¦ where this page comes from