Coding Gotchas

From Dreamwidth Notes
Jump to: navigation, search

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 );