Difference between revisions of "Coding Gotchas"
(Created page with "This page has a list of random weird Perl and DW gotchas == Gotchas == === use strict + my $foo if === <source lang="perl"> use strict; my $x = -1 if 0; # this condition is s...") |
m (→You can change the external value of non-reference scalars passed to a subroutine: Needs lang=text) |
||
(17 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
− | This page | + | This page documents coding "gotchas" where things might not turn out how you expect them to. |
− | == | + | == Dreamwidth specific gotchas == |
+ | |||
+ | === LJ::Entry->new always returns an LJ::Entry === | ||
+ | |||
+ | You might expect that given an invalid <code>ditemid</code>, you might get an undefined value back--but that is not the case. This is for efficiency's sake--entry and comment fetch requests are cached, and then when one of the entries is accessed (such as $entry->subject), all the entries or comments are requested all at once. Check the <code>$entry->valid</code> sub instead. | ||
+ | |||
+ | <source lang="perl"> | ||
+ | my $entry = LJ::Entry->new( $u, ditemid => $deleted_ditemid ); | ||
+ | print "Entry 1 is defined\n" if defined $entry; | ||
+ | # use this instead of checking if the entry is defined | ||
+ | print "Entry 1 is valid\n" if defined $entry->valid; | ||
+ | |||
+ | $entry = LJ::Entry->new( $u, ditemid => $valid_ditemid ); | ||
+ | print "Entry 2 is defined\n" if defined $entry; | ||
+ | print "Entry 2 is valid\n" if defined $entry->valid; | ||
+ | </source> | ||
+ | |||
+ | Returns | ||
+ | |||
+ | <source lang="text"> | ||
+ | Entry 1 is defined | ||
+ | Entry 2 is defined | ||
+ | Entry 2 is valid | ||
+ | </source> | ||
+ | |||
+ | === $r->OK is 0 === | ||
+ | |||
+ | $r->OK is 0, not 200 | ||
+ | |||
+ | === $r->redirect is an 'error' page === | ||
+ | |||
+ | For reasons that don't need exploring at this juncture, <tt>$r->redirect</tt> | ||
+ | ( and probably any other case when you return something besides <tt>$r->OK</tt> from a handler method ), | ||
+ | the method is treated as an 'error' page. | ||
+ | |||
+ | If you want to set headers, | ||
+ | you will have to use <tt>$r->err_header_out</tt> instead of <tt>$r->header_out</tt>. | ||
+ | |||
+ | === Updating strings requires string names to be changed, too === | ||
+ | |||
+ | See [[English-stripping]]. | ||
+ | |||
+ | == General Perl gotchas == | ||
+ | |||
+ | === You can change the external value of non-reference scalars passed to a subroutine === | ||
+ | |||
+ | <source lang="perl"> | ||
+ | use strict; | ||
+ | |||
+ | my $x; | ||
+ | |||
+ | print "x is '$x'\n"; | ||
+ | foo($x); | ||
+ | print "x is now '$x'\n"; | ||
+ | |||
+ | sub foo { $_[0] = "bar"; } | ||
+ | </source> | ||
+ | |||
+ | Returns | ||
+ | |||
+ | <source lang="text"> | ||
+ | x is '' | ||
+ | x is now 'bar' | ||
+ | </source> | ||
=== use strict + my $foo if === | === use strict + my $foo if === | ||
Line 8: | Line 71: | ||
use strict; | use strict; | ||
− | my $x = -1 if 0; # | + | my $x = -1 if 0; # intentional false, for example. |
− | $x = 1; # This accesses a *global, | + | $x = 1; # This accesses a *global, persistent across requests* $x |
</source> | </source> | ||
+ | |||
+ | The condition can be anything, and this bug only happens if the "my $x" line does not execute because of the condition, if the condition is true then it will end up using the local as expected. | ||
strict does '''not''' complain about this. | strict does '''not''' complain about this. | ||
− | Do the following instead | + | Do the following instead: |
<source lang="perl"> | <source lang="perl"> | ||
Line 23: | Line 88: | ||
$x = 1; | $x = 1; | ||
</source> | </source> | ||
+ | |||
+ | === Useless use of private variable in void context === | ||
+ | |||
+ | If you have code such as the following, you may get a totally nonsensical error: | ||
+ | |||
+ | <source lang="perl"> | ||
+ | my $foo = 0; | ||
+ | my $bar = 1; | ||
+ | |||
+ | my @baz = $foo, $bar; | ||
+ | </source> | ||
+ | |||
+ | Which causes an error of "Useless use of private variable in void context" -- you want to do the following instead: | ||
+ | |||
+ | <source lang="perl"> | ||
+ | my $foo = 0; | ||
+ | my $bar = 1; | ||
+ | |||
+ | my @baz = ( $foo, $bar ); | ||
+ | </source> | ||
+ | |||
+ | [[Category:Development]] |
Latest revision as of 23:29, 18 August 2014
This page documents coding "gotchas" where things might not turn out how you expect them to.
Dreamwidth specific gotchas
LJ::Entry->new always returns an LJ::Entry
You might expect that given an invalid ditemid
, you might get an undefined value back--but that is not the case. This is for efficiency's sake--entry and comment fetch requests are cached, and then when one of the entries is accessed (such as $entry->subject), all the entries or comments are requested all at once. Check the $entry->valid
sub instead.
my $entry = LJ::Entry->new( $u, ditemid => $deleted_ditemid ); print "Entry 1 is defined\n" if defined $entry; # use this instead of checking if the entry is defined print "Entry 1 is valid\n" if defined $entry->valid; $entry = LJ::Entry->new( $u, ditemid => $valid_ditemid ); print "Entry 2 is defined\n" if defined $entry; print "Entry 2 is valid\n" if defined $entry->valid;
Returns
Entry 1 is defined Entry 2 is defined Entry 2 is valid
$r->OK is 0
$r->OK is 0, not 200
$r->redirect is an 'error' page
For reasons that don't need exploring at this juncture, $r->redirect ( and probably any other case when you return something besides $r->OK from a handler method ), the method is treated as an 'error' page.
If you want to set headers, you will have to use $r->err_header_out instead of $r->header_out.
Updating strings requires string names to be changed, too
See English-stripping.
General Perl gotchas
You can change the external value of non-reference scalars passed to a subroutine
use strict; my $x; print "x is '$x'\n"; foo($x); print "x is now '$x'\n"; sub foo { $_[0] = "bar"; }
Returns
x is '' x is now 'bar'
use strict + my $foo if
use strict; my $x = -1 if 0; # intentional false, for example. $x = 1; # This accesses a *global, persistent across requests* $x
The condition can be anything, and this bug only happens if the "my $x" line does not execute because of the condition, if the condition is true then it will end up using the local as expected.
strict does not complain about this.
Do the following instead:
use strict; my $x; $x = -1 if 0; $x = 1;
Useless use of private variable in void context
If you have code such as the following, you may get a totally nonsensical error:
my $foo = 0; my $bar = 1; my @baz = $foo, $bar;
Which causes an error of "Useless use of private variable in void context" -- you want to do the following instead:
my $foo = 0; my $bar = 1; my @baz = ( $foo, $bar );