From: ccc31807 on 8 Jun 2010 14:10 This is embarrassing! I read an input file, split each row on the separators, pick out the unique key (which consists of seven digits), create a hash element on the key, and read the other values into an anonymous hash. This has worked for years without a hitch. Yesterday, my user requested the app to print a calculated field, which is a list of names contained in a secondary file. I thought, "No problem, I'll just create a new element in my anonymous hash, concatenate each name unless the name already matched the string, and print it out." Didn't work, but the errors seemed to be random and arbitrary. After a couple of hours, I used bdf's trick to print out the hash, and discovered much to my embarrassment that the keys weren't the same. In the main loop where I created the hash, the keys were as expected and consisted of seven characters which are all digits. HOWEVER, in the loop where I created the additional hash element, the keys with leading zeros did not match. Here is an example of the hash: 0123456 => HASH(deadbeed) id => 0123456 name => joe gender => male new_field => 123456 => HASH(deadbeef) new_field => list of concatenated strings I read the main file and create the main hash on the unique key, one element of which is 'new_field' with an initial value of ' '. Then, I read a secondary file which contains the key and ATTEMPT to concatenate an element to the main hash element new_field. Instead, it creates a new hash element with the numeric value of the unique key instead of the string value. So, I guess my question is how I convert an integer to a string to preserve the leading zeros. According to MJD on his infrequently asked questions page, the answer is, "Try using a whip." But that doesn't tell me what kind of whip. http://perl.plover.com/IAQ/IAQlist.html#how_can_i_force_perl_to_treat_a_number_as_a_string CC.
From: Ralph Malph on 8 Jun 2010 14:19 > So, I guess my question is how I convert an integer to a string to > preserve the leading zeros. > > According to MJD on his infrequently asked questions page, the answer > is, "Try using a whip." But that doesn't tell me what kind of whip. > http://perl.plover.com/IAQ/IAQlist.html#how_can_i_force_perl_to_treat_a_number_as_a_string The whip I usually use is string concatenation or variable interpolation within double quotes. Something like my $number=5; my $string="000".$number; Surely there are several ways to do this. This always works for me! :)
From: Uri Guttman on 8 Jun 2010 14:26 >>>>> "c" == ccc31807 <cartercc(a)gmail.com> writes: c> After a couple of hours, I used bdf's trick to print out the hash, and c> discovered much to my embarrassment that the keys weren't the same. In c> the main loop where I created the hash, the keys were as expected and c> consisted of seven characters which are all digits. HOWEVER, in the c> loop where I created the additional hash element, the keys with c> leading zeros did not match. Here is an example of the hash: what trick? use Data::Dumper and no trick is needed. c> 0123456 => HASH(deadbeed) c> id => 0123456 that is an OCTAL literal. when parsed into perl it will be converted to an integer and later printed in decimal. if those are always keys which means strings, never print or use them without quotes. don't think of them as numbers but strings with all digits. c> So, I guess my question is how I convert an integer to a string to c> preserve the leading zeros. if you already have corrupted numbers, use sprintf to pad them with zeros. but i suspect you will still have nasty errors as you will have converted from the literal octal value now to a decimal. you can sprintf the number back in octal to compensate. the proper solution is to never let perl see those as literal octal numbers but always as strings. i dunno what your code is doing (as you didn't post any) to make this happen. are you doing an eval on some incoming data? that is a no-no! do a proper parse and you can keep those keys as strings. uri -- Uri Guttman ------ uri(a)stemsystems.com -------- http://www.sysarch.com -- ----- Perl Code Review , Architecture, Development, Training, Support ------ --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
From: ccc31807 on 8 Jun 2010 14:45 On Jun 8, 2:26 pm, "Uri Guttman" <u...(a)StemSystems.com> wrote: > dunno what your code is doing (as you didn't post any) to make this > happen. are you doing an eval on some incoming data? that is a no-no! do > a proper parse and you can keep those keys as strings. This is what I'm doing. The main file looks like this: 0123456|joe|male|etc ... which I manipulate as follows: my ($id, $name, $gender, @rest) = split /\|/; $main_hash{$id} = { id => $id, name => $name. gender => $gender, rest => @rest, new_value => ' ', }; The secondary file looks like this: 0123456|this|etc ... 0123456|is|etc ... 0123456|a|etc ... 0123456|list|etc ... 0123456|of|etc ... 0123456|strings|etc ... which I manipulate as follows: my ($id, $string, @rest) = split /\|/; $main_hash{$id}{new_value} .= $string unless $main_hash{$id} {new_value} =~ /$string/; #the strings can be duplicated but I only want one of each So, should I double quote the $id when I use it as a hash key? That strikes me as idiosyncratic even for Perl. CC.
From: J. Gleixner on 8 Jun 2010 15:18
ccc31807 wrote: > On Jun 8, 2:26 pm, "Uri Guttman" <u...(a)StemSystems.com> wrote: >> dunno what your code is doing (as you didn't post any) to make this >> happen. are you doing an eval on some incoming data? that is a no-no! do >> a proper parse and you can keep those keys as strings. > > This is what I'm doing. > > The main file looks like this: > 0123456|joe|male|etc ... > > which I manipulate as follows: > my ($id, $name, $gender, @rest) = split /\|/; > $main_hash{$id} = { > id => $id, > name => $name. > gender => $gender, > rest => @rest, > new_value => ' ', > }; > > The secondary file looks like this: > 0123456|this|etc ... > 0123456|is|etc ... > 0123456|a|etc ... > 0123456|list|etc ... > 0123456|of|etc ... > 0123456|strings|etc ... > > which I manipulate as follows: > my ($id, $string, @rest) = split /\|/; > $main_hash{$id}{new_value} .= $string unless $main_hash{$id} > {new_value} =~ /$string/; #the strings can be duplicated but I only > want one of each > > So, should I double quote the $id when I use it as a hash key? That > strikes me as idiosyncratic even for Perl. > > CC. Provide actual code that we can run that shows your issue and so we can see what's happening. |