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:
The correct way of course would be to just write:print "type in something: "; my $line = <STDIN>; $line = chomp $line;
print "type in something: "; my $line = <STDIN>; chomp $line;
The above prints 1 1 1my @data = qw(foo bar baz); @data = map { s/./X/ } @data; print "@data\n";
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";
|| being higher precedence that above is the same asmy $filename = 'input.txt'; 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.open my $fh, '<', ($filename || die $!);
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 $!;
The annoying part here is that this works despite being incorrect.my @names = qw(A B C); foreach my $name (<@names>) { print "$name\n"; }
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"; }
That will try to match $_ with /x/my $x = 42; if ($x = /x/) { print "ok\n"; }
I am not saying it is not legitimate code. I am saying I see beginners write that by mistake without understanding what that means.
The above will return 0 despite it being false and will do it silently.my $x = 42; print is_foo_or(); sub is_foo_or { return foo($x) or $x; } sub foo { return 0; }
In reply to Little annoying mistakes ... of others by szabgab
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |