warning: non-DWIM behavior

L

Larry

Just thought I'd put out a warning for y'all to check your code against
a nasty "gotcha"

The 2 examples

int(rand() * 256)

and

int(rand * 256)

are *not* the same!! The second example is *not* what you want (unless
you want 0 all the time). Apparently the second example is actually
passing the typesplat "* 256" of all things (as if there's a chance
that's what anyone would want) into "rand" which somehow ends up the
same as rand(), so the second example is actually doing:

int(rand())

which explains the constant zeros.

Horrifyingly, I was using this code in an *encryption* routine with
results about what you'd expect. Thankfully, I hapenned to notice it
fairly quickly (just because I'm the type that would nose around inside
a supposedly encrypted file just to see if it smells normal... it most
decidedly did not)

This is not the sort of DWIM behavior I normally expect from Perl!
Ahh, well, perfection is not for this world. But... damn!!
 
J

John W. Krahn

Larry said:
Just thought I'd put out a warning for y'all to check your code against
a nasty "gotcha"

The 2 examples

int(rand() * 256)

and

int(rand * 256)

are *not* the same!! The second example is *not* what you want (unless
you want 0 all the time). Apparently the second example is actually
passing the typesplat "* 256" of all things (as if there's a chance
that's what anyone would want) into "rand" which somehow ends up the
same as rand(), so the second example is actually doing:

int(rand())

which explains the constant zeros.

Horrifyingly, I was using this code in an *encryption* routine with
results about what you'd expect. Thankfully, I hapenned to notice it
fairly quickly (just because I'm the type that would nose around inside
a supposedly encrypted file just to see if it smells normal... it most
decidedly did not)

This is not the sort of DWIM behavior I normally expect from Perl!
Ahh, well, perfection is not for this world. But... damn!!

A good example of why you should have warnings enabled!

$ perl -wle'print int(rand * 256)'
Argument "*main::256" isn't numeric in rand at -e line 1.
0


John
 
P

Paul Lalli

Larry said:
The 2 examples

int(rand() * 256)

and

int(rand * 256)

are *not* the same!!
Horrifyingly, I was using this code in an *encryption* routine with
results about what you'd expect.

You developed an *encryption* routine without warnings enabled?

Frankly, I think you deserve what you get. But I could just be a
bastard.

Paul Lalli
 
C

ced

Larry said:
Just thought I'd put out a warning for y'all to check your code against
a nasty "gotcha"

The 2 examples

int(rand() * 256)

and

int(rand * 256)

are *not* the same!! The second example is *not* what you want (unless
you want 0 all the time). Apparently the second example is actually
passing the typesplat "* 256" of all things (as if there's a chance
that's what anyone would want) into "rand" which somehow ends up the
same as rand(), so the second example is actually doing:

int(rand())
....

You're correct:

perl -MO=Deparse,-p -e 'print int(rand * 256)'
print ( int(rand(*256)) ) ;

( but, the 'use warnings' mantra will save you from self-inflicted
injury as was pointed out)
This is not the sort of DWIM behavior I normally expect from Perl!
Ahh, well, perfection is not for this world. But... damn!!

You get the same kind of DWIM with auto type conversion which
is so convenient:

perl -le 'print 4 * "3"'
12

But the same pitfalls exist: make that * 3 instead of 3 and you'll
get the
suprise you saw with rand():

perl -le 'print 4 * "* 3"'
0

Perl couldn't really be expected to know what you meant. But, at least
with
warnings enabled, Perl complains:

perl -wle 'print 4 * ("*3")'
Argument "*3" isn't numeric in multiplication (*) at -e line 1.
0

hth,
 
G

Glenn Jackman

At 2005-12-27 04:47PM said:
Horrifyingly, I was using this code in an *encryption* routine with
results about what you'd expect. Thankfully, I hapenned to notice it
fairly quickly (just because I'm the type that would nose around inside
a supposedly encrypted file just to see if it smells normal... it most
decidedly did not)

Gee, I always thought that was called "testing". I never would have
guessed "smelling".
 
L

Larry

Glenn said:
Gee, I always thought that was called "testing". I never would have
guessed "smelling".

Well, originally I had the parens in (I think because I had pasted that
code snippet from a web page) and I had already eyeballed a base64 dump
of the encrypted files to see if they looked fairly random and they
did. But something later posessed me to remove the parens when I came
accross that snippet of code again and I didn't think to do the base64
eyeball check again right away. But luckily I made an unrelated code
change later that same day which prompted me to eyeball-check it again.

I really should use warnings, you're right. I think the reason I
originally stopped was because I didn't like the way it complained
about me using an "undef" value... i.e.:

my $i;

...

++$i;

I really don't want to have to say:

my $i = 0;
 
P

Paul Lalli

Larry said:
I really should use warnings, you're right. I think the reason I
originally stopped was because I didn't like the way it complained
about me using an "undef" value... i.e.:

my $i;

...

++$i;

I really don't want to have to say:

my $i = 0;

What makes you think you'd have to do that? The above does not
generate a warning.
$ perl -wle'my $i; ++$i; print $i'
1

If you really do find a warning that you find intolerable, simply turn
it off for the small block in which you don't want warnings. Leave
them on everywhere else.

#!/usr/bin/perl
use strict;
use warnings;

my $i = 'foo';
my $j;
{
no warnings 'numeric';
$j = $i + 5;
}
print "J = $j\n";
__END__


See also:
perldoc perllexwarn

Paul Lalli
 
L

Larry

Paul said:
What makes you think you'd have to do that? The above does not
generate a warning.
$ perl -wle'my $i; ++$i; print $i'
1

Hmm... maybe it once did in a long-ago version of Perl? It was quite a
long time ago that I stopped.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top