jobsworth has asked for the wisdom of the Perl Monks concerning the following question:

i love perl but i wish to rant a bit. my script worked perfectly until i changed something somewhere else. the problem seems to be that perl does things behind your back like changing numbers to strings and back again instead of generating an error message. like microsoft windows very nice when it works but very difficult to fix when it does not. this code is a subroutine from a hit counter script which increments the counter in the file when you say Yes but otherwise not. it then goes on to generate a bmp file which contains the graphic of the hit counter. after many days and nights and much pondering i added the line sprintf and all was well. sprintf is what is happening behind your back all the time so why not now? please ignore the flock. it is supposed to make it multi-user. i don't know if it does or not. thank you for reading this.

sub opennumfile{ open(COUNT,$count) or die ("Can't open $count: $!"); flock(COUNT, 1); #shared lock for reading $c = <COUNT> ; close(COUNT) or die ("Can't close $count: $!"); if ($count =~ /\n$/) {chomp($c);} if (!defined($y = param('update'))){ $y = "Yes"; } if (uc($y) eq "YES"){ $c++; open(COUNTER,">$count") or die ("Can't open $count: $!"); flock(COUNTER, 2); #exclusive lock for writing print COUNTER "$c\n$somethingfile\n"; # path to the calling web page close(COUNTER) or die ("Can't close $count: $!"); } $c = sprintf("%d", $c); # essential line but only if $y ne "YES" $nim = $r = length($c); while ($r > 0) { $char[$r] = chop($c); $r--; } }

Replies are listed 'Best First'.
Re: sprintf number to string
by stevieb (Canon) on Aug 14, 2015 at 13:53 UTC

    What did you change somewhere else? I see you're not using use strict; or use warnings;, so I'd have to immediately assume that your at-a-distance change modified your unrestricted global variable $c somehow. Did you print "]$c[\n"; to see what it looked like before the sprintf call?

    The reason we lexical-ize variables is to prevent possible at-a-distance modification of variables that we don't expect, which makes troubleshooting extremely difficult. It's just too easy to clobber variables in other parts of the application without any warning or notification.

    I'm not saying this is what's happening, but it's my first guess if I was to troubleshoot the issue.

    "the problem seems to be that perl does things behind your back"

    perl only does this if you let it. By not using use strict; and use warnings;, you're running with scissors with a blindfold on.


      yes that is it. there was a my ($c); inside the subroutine which i moved outside. i always use strict. i never use warnings. i will do so. many thanks for your time and accurate observation. john
Re: sprintf number to string
by Athanasius (Archbishop) on Aug 14, 2015 at 14:04 UTC

    Hello jobsworth,

    Perhaps this will shed some light:

    (1) Without warnings:

    23:59 >perl -E "$c = 1; say(length $c);" 1 23:59 >perl -E "say(length $c);" 23:59 >perl -E "$c = sprintf('%d', $c); say(length $c);" 1 23:59 >

    (2) With warnings:

    23:59 >perl -wE "$c = 1; say(length $c);" 1 0:01 >perl -wE "say(length $c);" Name "main::c" used only once: possible typo at -e line 1. Use of uninitialized value in say at -e line 1. 0:01 >perl -wE "$c = sprintf('%d', $c); say(length $c);" Use of uninitialized value $c in sprintf at -e line 1. 1 0:01 >

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      salve Athanasius, non potero, gratum est: sed quia per exemplum perl poema modo sed 20 quid dicis. i non habent dicunt. gratias jobsworth
Re: sprintf number to string
by Crackers2 (Parson) on Aug 14, 2015 at 16:59 UTC
    Should this
    if ($count =~ /\n$/) {chomp($c);}
    be this
    if ($c =~ /\n$/) {chomp($c);}
    (or really just chomp; no need for the condition there I think)

    The way you have it now, $c will still have the newline at the end.

Re: sprintf number to string
by u65 (Chaplain) on Aug 14, 2015 at 13:55 UTC

    Aside from the usual suggestion to use strict and warning and format your code to enable a stranger to make more sense of it, can you show example input and output (actual and expected)?

      i agree that it is badly formatted and makes little sense. it is a can of worms which needs to be rewritten. but you know what they say - if it ain't broken don't fix it. it is supposed to look for a file and create it with permissions 666 if it does not exist. then read the number written inside, then increment the number and then write the number to the file. all this while other users may be trying to do the same thing. at the moment i have to create the file myself if it does not exist and set the permissions to 666. without sending you the entire script i do not know how to comply with your request. i have received the help i requested and i thank you for that.