develooper Front page | perl.perl5.porters | Postings from July 2013

[perl #119007] Different results using while/each and for/key when processing a dbm while running Perl 5.16.3 under Windows 7

From:
JOSEPHWALL99
Date:
July 25, 2013 05:11
Subject:
[perl #119007] Different results using while/each and for/key when processing a dbm while running Perl 5.16.3 under Windows 7
Message ID:
rt-3.6.HEAD-2552-1374715559-1526.119007-75-0@perl.org
# New Ticket Created by  JOSEPHWALL99 
# Please include the string:  [perl #119007]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org:443/rt3/Ticket/Display.html?id=119007 >


This is a bug report for perl from josephwall99@comcast.net,
generated with the help of perlbug 1.39 running under perl 5.16.3.


-----------------------------------------------------------------
[Please describe your issue here]

I have a simple script that reads through the ITunes music library looking for duplicate songs.
I have created a version of the script that processes a subset of the library. The input to the script is --

01 - Time Spent In Los Angeles.mp3
02 - A Whiter Shade Of Pale.mp3
jerry jeff walker - my old man (1).mp3
Jerry Jeff Walker - My Old Man (2).mp3
Waitresses - Christmas Wrapping (1).mp3
Waitresses - Christmas Wrapping (2).mp3
Waitresses - Christmas Wrapping.mp3.

The code that processes this input is --

#! /usr/bin/perl 
   use strict;
   use Win32;
#  use IO::Tee;
  
   my %COUNT; 

   my $total_count = 0;
   my $dupe_count = 0;
   my $total_dbms = 0; 
   my $dupes = 0;

   chdir('i:/') || die "Failed to change drive to I $!";
   open(SAMPLE, 'My_Music_Sample.txt') || die "Failed to open Music_Sample $!";
   dbmopen(%COUNT, "Count_Songs", 644) || die "Failed to open DBM $!";

   while (my $song_name = (<SAMPLE>)) {  
      chomp($song_name);
      if (-d $song_name) {
         print "Skipping directory $song_name\n";
         next;
         }
      $song_name =~ tr/A-Z/a-z/;
      next if ($song_name =~ /albumart/); 
      $song_name =~ s/[\\\/:\*\?"<>|]/ /g;
      $song_name =~ s/\.mp3$//i;
      $song_name =~ s/ *\(\d+\)//g;
      $song_name =~ s/-/_/g;
      $song_name =~ s// /g;
      my $song_count = $COUNT{$song_name};
      $song_count = 0 if ($song_count eq ''); 
      ++$song_count;
      $COUNT{$song_name} = $song_count;
      ++$total_count;
      }       

   dbmclose(%COUNT);
   dbmopen(%COUNT, "Count_Songs", 644) || die "Failed to open DBM $!";
   open DUPERPT, ">", "Dupe_Report.txt" || die "Failed to open Dupe_Report $!";

#  while (my ($song_name, $song_count) = each(%COUNT)) {
   foreach my $song_name (keys %COUNT) {
      my $song_count = $COUNT{$song_name};
      ++$total_dbms; 
      if ($song_count > 1) {
         print "Song $song_name has a count of $song_count\n"; 
         print DUPERPT "$song_name has a count of $song_count\n";
         ++$dupe_count;
         $dupes += $song_count;
         }
      $COUNT{$song_name} = 0; 
      }

   print "Total number of songs            = $total_count\n";
   print "Total number of dbm records read = $total_dbms\n";
   print "Total number of duplicate songs  = $dupe_count\n";
   $dupes -= $dupe_count;
   print "Total number of duplicates       = $dupes\n";
   print DUPERPT "Total number of songs read       = $total_count\n";           
   print DUPERPT "Total number of dbm records read = $total_dbms\n";
   print DUPERPT "Total number of duplicate songs  = $dupe_count\n";
   print DUPERPT "Total number of duplicates       = $dupes\n";

   closedir(MUSIC);
   close(DUPERPT);
   dbmclose(%COUNT);


If I run the script with the for/keys code operative, I get the following correct output --

jerry jeff walker _ my old man has a count of 2
waitresses _ christmas wrapping has a count of 3
Total number of songs read       = 7
Total number of dbm records read = 4
Total number of duplicate songs  = 2
Total number of duplicates       = 3

If I run the script with the while/each code operative, I consistenly get the following incorrect output --

jerry jeff walker _ my old man has a count of 2
Total number of songs read       = 7
Total number of dbm records read = 4
Total number of duplicate songs  = 1
Total number of duplicates       = 1

Note that the number of records read back from the dbm is the same in both instances.

When run under Linux, the two methods get identical results eqaul to what for/key returns under Windows.

A further complication is that the following code --

# usr/bin/perl -w
  use strict;
  use Fcntl;
  use AnyDBM_File;

  my $preferred_dbm = $AnyDBM_File::ISA[0];
  my %COUNT;
  tie(%COUNT, $preferred_dbm, "Count_Songs", O_RDONLY, 0644) || die "Failed to open dbm $!";

  if (%COUNT) {
     my $total_missed = 0;
     for my $song_name (keys %COUNT) {
         my $song_count = $COUNT{$song_name};  
         if ($song_count > 0) {
            print "Song $song_name has a count of $song_count\n";
            ++$total_missed;
            }
         } 
     print "Total number of dupes missed = $total_missed\n"; 
     } else {
     print "COUNT IS EMPTY\n";
     }

   untie(%COUNT);

when run against the closed dbm, always yields "COUNT IS EMPTY". This code also works as expected under Linux.

Sincerely,
Joe Wall

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
    category=core
    severity=medium
---
Site configuration information for perl 5.16.3:

Configured by cyg_server at Wed Mar 13 13:27:24 2013.

Summary of my perl5 (revision 5 version 16 subversion 3) configuration:
   
  Platform:
    osname=MSWin32, osvers=5.2, archname=MSWin32-x64-multi-thread
    uname=''
    config_args='undef'
    hint=recommended, useposix=true, d_sigaction=undef
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cl', ccflags ='-nologo -GF -W3 -MD -Zi -DNDEBUG -Ox -GL -fp:precise -DWIN32 -D_CONSOLE -DNO_STRICT -DWIN64 -DCONSERVATIVE -DPERL_TEXTMODE_SCRIPTS -DUSE_SITECUSTOMIZE -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO',
    optimize='-MD -Zi -DNDEBUG -Ox -GL -fp:precise',
    cppflags='-DWIN32'
    ccversion='14.00.40310.41', gccversion='', gccosandvers=''
    intsize=4, longsize=4, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=8
    ivtype='__int64', ivsize=8, nvtype='double', nvsize=8, Off_t='__int64', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='link', ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf -ltcg  -libpath:"C:\Perl64\lib\CORE"  -machine:AMD64'
    libpth=\lib
    libs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib  comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib  netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib  version.lib odbc32.lib odbccp32.lib comctl32.lib bufferoverflowU.lib msvcrt.lib
    perllibs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib  comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib  netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib  version.lib odbc32.lib odbccp32.lib comctl32.lib bufferoverflowU.lib msvcrt.lib
    libc=msvcrt.lib, so=dll, useshrplib=true, libperl=perl516.lib
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug -opt:ref,icf -ltcg  -libpath:"C:\Perl64\lib\CORE"  -machine:AMD64'

Locally applied patches:
    ACTIVEPERL_LOCAL_PATCHES_ENTRY

---
@INC for perl 5.16.3:
    C:/Perl64/site/lib
    C:/Perl64/lib
    .

---
Environment for perl 5.16.3:
    HOME (unset)
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=C:\Perl64\site\bin;C:\Perl64\bin;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;c:\Program Files (x86)\Intel\iCLS Client\;c:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Program Files (x86)\Common Files\Roxio Shared\DLLShared\;C:\Program Files (x86)\Common Files\Roxio Shared\10.0\DLLShared\
    PERL_BADLANG (unset)
    SHELL (unset)




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About