http://qs321.pair.com?node_id=728569

When I started to write this entry I noticed the your Perl bug Achilles heel by perrin which is similar but not really.
I am looking for bugs that you might not make any more but either you used to make or you know others often make it. Little annoyances that can easily trip the unaware without perl warning them.

While reading the Minimal Perl by Tim Maher I encountered two warnings about mistakes beginners might make. Based on those two I started to collect some little mistakes people can make in Perl but that perl does not catch.

The first two are based on the warnings from Minimal Perl:

chomp does not return the string

print "type in something: "; my $line = <STDIN>; $line = chomp $line;
The correct way of course would be to just write:
print "type in something: "; my $line = <STDIN>; chomp $line;

substitute returns true/false and not the changed string even in map

my @data = qw(foo bar baz); @data = map { s/./X/ } @data; print "@data\n";
The above prints 1 1 1

The correct way would be to let map return the changed value instead of the success/failure code of the substitution.

my @data = qw(foo bar baz); @data = map { s/./X/; $_} @data; print "@data\n";

|| has higher precedence than ,

my $filename = 'input.txt'; open my $fh, '<', $filename || die $!;
|| being higher precedence that above is the same as
open my $fh, '<', ($filename || die $!);
which means first the || is evaluated which will always be true (except of the stupid edge cases such as $filename being empty string or 0) so in normal circumstances everything will work but if the open fails, it still won't be reported.

The correct would be to either use or instead of || or put parentheses around the parameters of open(). Personally I try to write and teach this form:

my $filename = 'input.txt'; open(my $fh, '<', $filename) or die $!;

Perl 6-like constructs work in perl 5

A student of mine had to iterate over the values of an array so he wrote:
my @names = qw(A B C); foreach my $name (<@names>) { print "$name\n"; }
The annoying part here is that this works despite being incorrect.

We are talking about Perl 5 here!.

Using perl -MO=Deparse example.pl reveals what perl thought about the above code:

my(@names) = ('A', 'B', 'C'); use File::Glob (); foreach my $name (glob(join($", @names))) { print "$name\n"; }

magic $_ regex matching

my $x = 42; if ($x = /x/) { print "ok\n"; }
That will try to match $_ with /x/
If you are lucky you get Use of uninitialized value $_ in pattern match (m//) at code.pl line 32.. If you are unlucky and $_ already had a value the above will make the mistake silently.

I am not saying it is not legitimate code. I am saying I see beginners write that by mistake without understanding what that means.

or is weaker than return

Based on the example given by rhesa
my $x = 42; print is_foo_or(); sub is_foo_or { return foo($x) or $x; } sub foo { return 0; }
The above will return 0 despite it being false and will do it silently.

Question

So what are your annoyances or rather those bugs that you see others make while you think they are simple?