excluding undefined variables

excluding undefined variables

am 13.12.2010 02:11:45 von Shawn Wilson

i'm trying to exclude undefined variables for that are to be put into
a sql database date field, but none of this is working:

sub correctdate { # make valid sql DATE field
my $date = $_[ 0 ];

my ($month, $day, $year) = split / /, $date if defined( $date );

$day =~ s/,//g if defined( $day );

my %monnum = qw(
January 01 February 02 March 03 April 04 May 05
June 06 July 07 August 08 September 09 October 10
November 11 December 12
);

if( $year && $month && $day ) {
my $corrected = "$year-$monnum{$month}-$day";
} else {
my $corrected = "0000-00-00";
}

return $corrected;
}

my dates are listed such as 'December 1, 2009'
and, just to confirm what i was saying in my prior email, when i
really care about the timestamp, i do:
$pageth->execute( $vid, time(), $content );

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: excluding undefined variables

am 13.12.2010 02:14:51 von Shawn Wilson

On Sun, Dec 12, 2010 at 8:11 PM, shawn wilson wrote:
> i'm trying to exclude undefined variables for that are to be put into
> a sql database date field, but none of this is working:

errr, sorry, my error with the current code is:
Global symbol "$corrected" requires explicit package name at
../uscg-get.pl line 139.
line 139 is 'return $corrected;'

>
> sub correctdate { =A0 =A0 =A0 =A0 =A0 =A0 # make valid sql DATE field
> =A0 my $date =3D $_[ 0 ];
>
> =A0 my ($month, $day, $year) =3D split / /, $date if defined( $date );
>
> =A0 $day =3D~ s/,//g if defined( $day );
>
> =A0 my %monnum =3D qw(
> =A0 =A0 =A0January 01 =A0February 02 =A0March 03 =A0April 04 =A0May 05
> =A0 =A0 =A0June 06 =A0July 07 =A0August 08 =A0September 09 =A0October 10
> =A0 =A0 =A0November 11 December 12
> =A0 );
>
> =A0 if( $year && $month && $day ) {
> =A0 =A0 =A0my $corrected =3D "$year-$monnum{$month}-$day";
> =A0 } else {
> =A0 =A0 =A0my $corrected =3D "0000-00-00";
> =A0 }
>
> =A0 return $corrected;
> }
>
> my dates are listed such as 'December 1, 2009'
> and, just to confirm what i was saying in my prior email, when i
> really care about the timestamp, i do:
> $pageth->execute( $vid, time(), $content );
>

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: excluding undefined variables

am 13.12.2010 04:03:04 von Brian Fraser

--20cf3054a2a55a8ebd049741f1c8
Content-Type: text/plain; charset=ISO-8859-1

You are declaring $corrected within the if block -- After it ends, the
variable goes out of scope, making a strict[0] Perl blow up in your face. As
you have warnings enabled, it shows that message (which you can look up in
perldiag is you don't quite get [1]).

The solution is simple: You just need to widen the scope of $corrected -
Which is to say, declare it outside of the if:

> my $corrected;

if( $year && $month && $day ) {
> $corrected = "$year-$monnum{$month}-$day";
> } else {
> $corrected = "0000-00-00";
> }
>
> return $corrected;
>

Also, if I may, a word about your code: You keep testing some variables for
definedness, but don't do anything when they are undefined, so you end up
piling on checks. Wouldn't it be simpler to return early? For instance, if
$date isn't defined, nothing else is going to work, so why not return there?

Brian.

[0] http://perldoc.perl.org/strict.html
[1] http://perldoc.perl.org/perldiag.html

--20cf3054a2a55a8ebd049741f1c8--

Re: excluding undefined variables

am 13.12.2010 07:05:01 von jwkrahn

shawn wilson wrote:
> i'm trying to exclude undefined variables for that are to be put into
> a sql database date field, but none of this is working:
>
> sub correctdate { # make valid sql DATE field
> my $date = $_[ 0 ];
>
> my ($month, $day, $year) = split / /, $date if defined( $date );

That may not work correctly:

perldoc perlsyn
[ SNIP ]
Statement Modifiers
[ SNIP ]
NOTE: The behaviour of a "my" statement modified with a
statement modifier conditional or loop construct
(e.g. "my $x if ...") is undefined. The value of the "my"
variable may be "undef", any previously assigned value, or
possibly anything else. Don't rely on it. Future versions of
perl might do something different from the version of perl you
try it out on. Here be dragons.

You probably want something like:

defined $date and my ( $month, $day, $year ) = split /[\s,]+/, $date;


> $day =~ s/,//g if defined( $day );
>
> my %monnum = qw(
> January 01 February 02 March 03 April 04 May 05
> June 06 July 07 August 08 September 09 October 10
> November 11 December 12
> );
>
> if( $year&& $month&& $day ) {
> my $corrected = "$year-$monnum{$month}-$day";
> } else {
> my $corrected = "0000-00-00";
> }

my() creates a variable that is only visible inside the scope of the {}
braces. You probably want something like:

my $corrected = $year && $month && $day
? "$year-$monnum{$month}-$day"
: "0000-00-00";

> return $corrected;
> }

Or perhaps you could do something like this:

sub correctdate { # make valid sql DATE field
my $date = $_[ 0 ];

my %monnum = qw(
January 1 February 2 March 3 April 4
May 5 June 6 July 7 August 8
September 9 October 10 November 11 December 12
);

my ( $month, $day, $year ) = defined $date
? map( $monnum{ $_ } || $_, split /[\s,]+/, $date )
: ( 0, 0, 0 );

return sprintf '%04d-%02d-%02d', $year, $month, $day;
}


> my dates are listed such as 'December 1, 2009'
> and, just to confirm what i was saying in my prior email, when i
> really care about the timestamp, i do:
> $pageth->execute( $vid, time(), $content );


John
--
Any intelligent fool can make things bigger and
more complex... It takes a touch of genius -
and a lot of courage to move in the opposite
direction. -- Albert Einstein

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/

Re: excluding undefined variables

am 13.12.2010 07:47:15 von Shawn Wilson

On Mon, Dec 13, 2010 at 1:05 AM, John W. Krahn wrote:
> shawn wilson wrote:
>>
>> i'm trying to exclude undefined variables for that are to be put into
>> a sql database date field, but none of this is working:
>>
>> sub correctdate { =A0 =A0 =A0 =A0 =A0 =A0 # make valid sql DATE field
>> =A0 =A0my $date =3D $_[ 0 ];
>>
>> =A0 =A0my ($month, $day, $year) =3D split / /, $date if defined( $date )=
;
>
> That may not work correctly:
>
> perldoc perlsyn
> [ SNIP ]
> =A0 Statement Modifiers
> [ SNIP ]
> =A0 =A0 =A0 NOTE: The behaviour of a "my" statement modified with a
> =A0 =A0 =A0 statement modifier conditional or loop construct
> =A0 =A0 =A0 (e.g. "my $x if ...") is undefined. =A0The value of the "my"
> =A0 =A0 =A0 variable may be "undef", any previously assigned value, or
> =A0 =A0 =A0 possibly anything else. =A0Don't rely on it. =A0Future versio=
ns of
> =A0 =A0 =A0 perl might do something different from the version of perl yo=
u
> =A0 =A0 =A0 try it out on. =A0Here be dragons.
>
> You probably want something like:
>
> defined $date and my ( $month, $day, $year ) =3D split /[\s,]+/, $date;
>
>
>> =A0 =A0$day =3D~ s/,//g if defined( $day );
>>
>> =A0 =A0my %monnum =3D qw(
>> =A0 =A0 =A0 January 01 =A0February 02 =A0March 03 =A0April 04 =A0May 05
>> =A0 =A0 =A0 June 06 =A0July 07 =A0August 08 =A0September 09 =A0October 1=
0
>> =A0 =A0 =A0 November 11 December 12
>> =A0 =A0);
>>
>> =A0 =A0if( $year&& =A0$month&& =A0$day ) {
>> =A0 =A0 =A0 my $corrected =3D "$year-$monnum{$month}-$day";
>> =A0 =A0} else {
>> =A0 =A0 =A0 my $corrected =3D "0000-00-00";
>> =A0 =A0}
>
> my() creates a variable that is only visible inside the scope of the {}
> braces. =A0You probably want something like:
>
> my $corrected =3D $year && $month && $day
> =A0 =A0? "$year-$monnum{$month}-$day"
> =A0 =A0: "0000-00-00";
>
>> =A0 =A0return $corrected;
>> }

the above should work. thanks.

>
> Or perhaps you could do something like this:
>
> sub correctdate { =A0 =A0 =A0 =A0 =A0 =A0 # make valid sql DATE field
> =A0 =A0my $date =3D $_[ 0 ];
>
> =A0 =A0my %monnum =3D qw(
> =A0 =A0 =A0 =A0January =A0 =A01 =A0February =A02 =A0March =A0 =A0 3 =A0Ap=
ril =A0 =A0 4
> =A0 =A0 =A0 =A0May =A0 =A0 =A0 =A05 =A0June =A0 =A0 =A06 =A0July =A0 =A0 =
=A07 =A0August =A0 =A08
> =A0 =A0 =A0 =A0September =A09 =A0October =A010 =A0November 11 =A0December=
12
> =A0 =A0 =A0 =A0);
>
> =A0 =A0my ( $month, $day, $year ) =3D defined $date
> =A0 =A0 =A0 =A0? map( $monnum{ $_ } || $_, split /[\s,]+/, $date )
> =A0 =A0 =A0 =A0: ( 0, 0, 0 );
>
> =A0 =A0return sprintf '%04d-%02d-%02d', $year, $month, $day;
> =A0 =A0}
>

though that might work, it looks a bit complicated - i hate using a
ton of $_ - that code was a pain to understand... i'd use it if i
didn't have to maintain it :)

thanks for your help. i'll use the former first thing tomorrow.

--
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
http://learn.perl.org/