> On Wed, Oct 13, 2004 at 04:33:14PM -0400, Marc M. Adkins wrote:
> > I have been getting an annoying warning about dereferencing
> an unreferenced
> > scalar.  Sometimes it comes out in such a way that it
> misses $SIG{__WARN__}
> > redirection.  After much trial and error I tracked it down, sort of.
> >
> > Here's the punch line:  it doesn't happen unless I use
> fetchall_hashref().
>
> It's fixed in the (as yet unannounced) DBI 1.45 release.

Yesterday (10/22) I found that ActiveState had updated their PPM repository 
and I downloaded and installed DBI 1.45:

ppm> query DBI
Querying target 1 (ActivePerl 5.8.4.810)
  1. DBI          [1.45] Database independent interface for Perl
ppm> query DBD-ODBC
Querying target 1 (ActivePerl 5.8.4.810)
  1. DBD-ODBC     [1.11] ODBC Driver for DBI
ppm>

Unfortunately, my test program (attached, same as previous version) is still 
saying the same thing (two runs, second demonstrates problem):

D:\CaseLaw>c:\temp\unref.pl
Step 1:  Database query
     16392:  db_denydatareader
     16393:  db_denydatawriter
         3:  INFORMATION_SCHEMA
     16384:  db_owner
         2:  guest
     16390:  db_datareader
     16385:  db_accessadmin
     16389:  db_backupoperator
         1:  dbo
         4:  system_function_schema
     16391:  db_datawriter
         0:  public
     16386:  db_securityadmin
     16387:  db_ddladmin
         5:  servman
Step 2:  Copy files
  Copied readme.txt
  Copied shortcut.cpp
  Copied SHORTCUT.DEF
  Copied Shortcut.MAK
  Copied Shortcut300.MAK

D:\CaseLaw>c:\temp\unref.pl 1
Step 1:  Database query
     16392:  db_denydatareader
     16393:  db_denydatawriter
         3:  INFORMATION_SCHEMA
     16384:  db_owner
         2:  guest
     16390:  db_datareader
     16385:  db_accessadmin
     16389:  db_backupoperator
         1:  dbo
         4:  system_function_schema
     16391:  db_datawriter
         0:  public
     16386:  db_securityadmin
     16387:  db_ddladmin
         5:  servman
Step 2:  Copy files
Attempt to free unreferenced scalar: SV 0x1c6ca04 at
C:/Perl/lib/File/Copy.pm line 91.
  Copied readme.txt
Attempt to free unreferenced scalar: SV 0x1c66d9c at
C:/Perl/lib/File/Copy.pm line 91.
  Copied shortcut.cpp
Attempt to free unreferenced scalar: SV 0x1c66dfc at
C:/Perl/lib/File/Copy.pm line 91.
  Copied SHORTCUT.DEF
Attempt to free unreferenced scalar: SV 0x1c6e89c at
C:/Perl/lib/File/Copy.pm line 91.
  Copied Shortcut.MAK
Attempt to free unreferenced scalar: SV 0x1c6e8a8 at
C:/Perl/lib/File/Copy.pm line 91.
  Copied Shortcut300.MAK

D:\CaseLaw>

This is Windows 2000, ActiveState Perl 5.8.4.  I didn't think to check the 
version of File::Copy.  But the problem is connected somehow to (non-)use of 
fetchall_hashref().

Is there anything I can do to test this further that doesn't require a C 
compiler / debugger?  We aren't provided with those tools (or the time to use 
them) at work and I don't have a working Windows system at home any more.

This is not a showstopper for me.  I've already modified all of my code to 
avoid fetchall_hashref().  Well, almost all of my code, I still see the error 
from time to time so I must have missed something somewhere...

mma
use     strict;
use     warnings;

use     DBI;
use     File::Copy;
use     File::Path;
use     File::Spec;

use     constant    TEMP_DIR    =>  'C:\\\temp';

print "Step 1:  Database query\n";

my  $DSN  = 'DBI:ODBC:' . join ';', split /\n/s, <<DSN;
DRIVER=SQL Server
Trusted_Connection=Yes
APP=Microsoft Open Database Connectivity
DATABASE=master
SERVER=Tech14
DSN

my  $dbms = DBI->connect($DSN, undef, undef, {
                AutoCommit  => 1,
                PrintError  => 0,
                RaiseError  => 1
            });

my  $stmt = $dbms->prepare(<<SQL);
    select *
      from sysusers
SQL

$stmt->execute;

my  $list = undef;

if (@ARGV) {
    # This causes:
    #       Attempt to free unreferenced scalar
    #   errors:
    $list = $stmt->fetchall_hashref('uid');
} else {
    # This doesn't cause the error:
    my  %list = ( );
    
    while (my $rec = $stmt->fetchrow_hashref) {
        $list{$rec->{uid}} = $rec;
    }
    
    $list = \%list;
}

$stmt->finish;

printf "  %8d:  %s\n", $_->{uid}, $_->{name}
    for values %$list;

print "Step 2:  Copy files\n";

my  $dstDir = File::Spec->catfile(TEMP_DIR, 'dest');
my  $srcDir = File::Spec->catfile(TEMP_DIR, 'source');

rmtree($dstDir);
mkpath($dstDir);

die "Unable to open source directory\n  $!\n"
    unless opendir SOURCE, $srcDir;

while (my $item = readdir(SOURCE)) {
    next if $item =~ /^\./;
    
    my  $dst = File::Spec->catfile($dstDir, $item);
    my  $src = File::Spec->catfile($srcDir, $item);
    
    # The unreferenced scalar error occurs here...
    
    if (copy($src, $dst)) {
        print "  Copied $item\n";
    } else {
        warn "  Unable to copy $item\n  $!\n"
    }
}

closedir SOURCE;

Reply via email to