in reply to capturing entries from the Registry

Some explanation of what you ARE getting would be very helpful. Other than that you obviously have the push commented out, so it wont work. If it isn't commented out though it looks like you are pushing the _same_ reference to $rec over and over. Move the my $ref; down into the next loop and it should work as expected. I'm not sure why you are looping over the keys though. It looks like you could just do hash lookups instead of the for my $item (keys %vals) loop.

$rec->{app} = $vals{DisplayName}[2] if ( exists $vals{DisplayName}); $rec->{path} = $vals{InstallSource}[2] if ( exists $vals{InstallSource +});

___________
Eric Hodges

Replies are listed 'Best First'.
Re^2: capturing entries from the Registry
by blueAdept (Beadle) on Jun 10, 2004 at 17:39 UTC
    Because $rec is declared within the loop the hash/reference storage with the array is OK.(if uncommented as you said)

    Initially when I tried to prove this I saw the same memory address printed each iteration - so I thought you were onto something. I always thought declaration of a lexical within a loop meant new memory was allocated at that declaration, but apparently perl is smart enough that if you're not storing a reference away of the variable that it doesn't allocate new space for it on the next iteration.

    Simply storing away a reference to the variable though changes all that though.

    my @array; for ( 0 .. 5) { my $foo; $foo->{x} = $_; print "$foo->{x} - (Foo = " . $foo . ")\n"; push @array, $foo if (defined($ARGV[0])); } for (my $y = 0; $y < scalar(@array); $y++) { print "Stored Value at $y: $array[$y]->{x}\n"; } =pod When run without $ARGV[0] being defined: 0 - (Foo = HASH(0x182f168)) 1 - (Foo = HASH(0x182f168)) 2 - (Foo = HASH(0x182f168)) 3 - (Foo = HASH(0x182f168)) 4 - (Foo = HASH(0x182f168)) 5 - (Foo = HASH(0x182f168)) and with it defined: 0 - (Foo = HASH(0x182f168)) 1 - (Foo = HASH(0x1825490)) 2 - (Foo = HASH(0x18254d8)) 3 - (Foo = HASH(0x1825520)) 4 - (Foo = HASH(0x1825568)) 5 - (Foo = HASH(0x18255b0)) Stored Value at 0: 0 Stored Value at 1: 1 Stored Value at 2: 2 Stored Value at 3: 3 Stored Value at 4: 4 Stored Value at 5: 5 =cut

      His my needs to be inside the loop though. Here is his

      my $rec; $x->GetValues(\%vals ); for my $item (keys %vals) {

      He then assigns stuff to $rec inside the for loop, not to $item, if it where $item then he would be fine. So the my $rec needs moved down a few lines like..

      $x->GetValues(\%vals ); for my $item (keys %vals) { my $rec;

      But this still doesn't get the desired results because he is looping over the hash keys instead of just looking up the values like i showed in my last post.


      ___________
      Eric Hodges
        Oh God,...Tried few things to no avail!

        But I think I know what to do - ...I think!! - I will go through the %vals and get apps names, save the apps names in an array, go through each element in the array and rematch it against the %vals again and obtain the InstallSource this time round...I will give this a spin and see

        Thanks for your help.

        I'll be back. btw: how do I get rid of the empty registry entries?
        this is an example of the registry dump of an empty registry record;
        $VAR1 = { '' => [ '', 1, '' ] };
        I tried the followin to to avail!
        $x->GetValues(\%vals ); #print Dumper \%vals; for my $item (keys %vals) { #next if ($item eq ''); #din't work #next if ($item=~ /\W+/g ); # nor did this #next if ($item=~ /\W/g ); # no #next if ($item =~ /^[^\w]/); # no next unless ($item !~ /\W/); #no print "$item"; } print "---------\n";
        Thanks for the help.

        UPDATE1 *******Please ignore the above******

        This has worked;
        $x->GetValues(\%vals ); #print Dumper \%vals; $rec->{app} = $vals{DisplayName}[2] if ( exists $vals{Display +Name}); $rec->{path} = $vals{InstallSource}[2] if ( exists $vals{Inst +allSource}); print "App : $rec->{app} print "Path :$rec->{path} \n"; print "---------\n";
        but, if the install source doesn't exits the this is display I get back;
        Use of uninitialized value in concatenation (.) or string at U:\script +s\listapps4.pl line 23. App : --------- Use of uninitialized value in concatenation (.) or string at U:\script +s\listapps4.pl line 23. App : --------- App : Apple Quicktime Pro 5.0.2 --------- App : Apple Quicktime Pro 5.0.2 --------- App : Apple Quicktime Pro 5.0.2 --------- App : Apple Quicktime Pro 5.0.2 --------- App : Apple Quicktime Pro 5.0.2 --------- App : Apple Quicktime Pro 5.0.2 --------- App : Apple Quicktime Pro 5.0.2 --------- App : Apple Quicktime Pro 5.0.2 --------- App : Apple Quicktime Pro 5.0.2 --------- App : Apple Quicktime Pro 5.0.2 --------- App : Apple Quicktime Pro 5.0.2 --------- App : Internet Explorer Q837251 ---------
        And Not sure why is some entries are duplicated UPDATE2 ********** Ok, This gor rid of the errors
        $rec->{app} = $vals{DisplayName}[2] if ( exists $vals{DisplayName}); $rec->{path} = $vals{InstallSource}[2] if ( exists $vals{Inst +allSource}); print "$rec->{app}" if ($rec->{app}); print "$rec->{path}" if ($rec->{path});
        But still don't know why Im still getting duplicates? UPDATE3 ****************** Ok, I got around it this, but don't know if its the best solution?
        $x->GetValues(\%vals ); $rec->{app} = $vals{DisplayName}[2] if ( exists $vals{Display +Name}); if ( exists $vals{InstallSource}) { $rec->{path} = $vals{InstallSource}[2]; } else { $rec->{path} = 'N/A'; } push (@source,$rec) if ($rec->{app}); } $Key->Close; } } print "\nListing Application information\n"; for my $apps (@source) { print "DisplayName\t: $apps->{app}"; print "InstallSource\t: $apps->{path}"; print "------------------------------------------------\n"; }
        But it works,...Thanks very much