Fog Creek Software
Discussion Board




"magical" autoincrement

So I've been programming perl for about 5 years now, and though I know that I'm no guru, I thought that I had a pretty good handle on how it works, and most of its in's and out's.

Well today I found a new feature that would have given me a hard to find bug.

I was looping over a list, and incrementing each's value in a hash by one every time.  I was assuming that initially each hash element's value would be undefined, and thus when incremented it would get the value of 1.  Here is the pseudo-code:

foreach $k ( @some_list ) {
  $hash->{ $k }++;
}

I am using the hash later in numeric context, it contains results for printing to a web-page.

I had warnings on, and so perl complained to me about using an undefined value.  So I decided to clean it up, and felt a little bit anal in the process since I "knew" that it would never be a problem.

Of course, what happens if that hash entry isn't undefined, but is actually set to some string, say "foo"?  By reasoning about the way the rest of perl works, I figured that it would convert "foo" to a number ( 0 ) and then increment that.  Shouldn't be problem I thought, which is why I was feeling anal.

So I tested it.  "foo"++ in perl is "fop".  It increments it _alphabetically_.

I was caught completely off-guard.  Looked it up in programming perl, and there it is, in the Autoincrement and Autodecrement section: "Magical Autoincrement".

Morals of the story:
1. Assume nothing, and don't worry about being too "anal" about checking for boundary conditions
2. Sometimes you don't know as much of a language as you thought.  See #1.

Andrew Hurst
Friday, May 07, 2004

Moral 0: Never rely on the value of an uninitialized variable.

Brian
Friday, May 07, 2004

Ha. yeah I should have added that one.

Andrew Hurst
Friday, May 07, 2004

I got bitten by something similar (at home) the other day in VB .NET.  In VB .NET (unlike VB6) variables have block scope; a variable initialized inside a For Each...Next loop won't be accessible outside it.  What I assumed was that this meant the variable was destroyed after each For Each step and reinitialized on the next one, so my

Dim ii as Int32

would set ii equal to zero each time through.

So I was going through DataTable rows with While ii < Rows.Count.  But only three of my DataTables went through their rows; the other ones showed as if they had zero rows.

Turns out, while ii only lived inside the block, ii was _not_ reDimmed and reinitialized each time through.  So if ii got to, say, 50 on the last For Each, then on the next one it would start at 50...and if the object had less than 50 rows, it would just skip the whole thing.  Instead I had to use

Dim ii as Int32 = 0

which properly reinitialized ii each time through.

All this, just for a moment, made me understand some people's vehement devotion to C# over VB...but luckily I got over it.  :)

Kyralessa
Friday, May 07, 2004

> It increments it _alphabetically_.

ROTFLMAO!

That's pretty funny actually. Makes perfect sense to the linguistic mind of the languages creator, even if it is almost completely useless. What comes after z?

Perl fan
Friday, May 07, 2004

"aa" comes after "z" -- just like the columns in Excel, say.

Of course, I can't help but wonder what happens in a non-English locale...

John C.
Friday, May 07, 2004

I would think the correct way would be:

foo
fop
...
foz
fpa
fpb

etc

Perl fan
Saturday, May 08, 2004

Shouldn't that be:

foreach $k ( @some_list ) {
  $hash{ $k }++;            // without the ->
}

Matthew Lock
Saturday, May 08, 2004

Used without ->:

foreach $k ( @some_list ) {
  $hash{ $k }++;
}

means there is a %hash somewhere

Used with ->:

foreach $k ( @some_list ) {
  $hash -> { $k }++;
}

means that $hash is a reference to a hash, for example:

my %foo_hash;
my $hash = \%foo_hash;

Rene

René Nyffenegger
Saturday, May 08, 2004

Yep, Rene was right.  I was using a hash reference, not a hash.

Andrew Hurst
Saturday, May 08, 2004

> Makes perfect sense to the linguistic mind of the languages
> creator, even if it is almost completely useless.

Actually, I've found it useful more than once. Thanks, Larry!

Michael Eisenberg
Monday, May 10, 2004

*  Recent Topics

*  Fog Creek Home