Dave
Dave

Reputation: 19150

Why do I get a filename of ARRAY(0x7fd5c22f7cd8) when trying to unzip with Perl's Archive::Extract?

I'm using Perl 5.12 on Mac 10.5.7. I have a JAR file, that I wish to unzip, and then process a file matching a file pattern. I'm having trouble figuring out how to iterate over the results of unzipping. I have ...

### build an Archive::Extract object ###
my $ae = Archive::Extract->new( archive => $dbJar );

### what if something went wrong?
my $ok = $ae->extract or die $ae->error;

### files from the archive ###
my @files   = $ae->files;

for (@files) {
    print "file : $_\n";

But there is only one thing returned from the loop -- "ARRAY(0x7fd5c22f7cd8)". I know there are lots of files in the archive, so I'm curious what I"m doing wrong here. - Dave

Upvotes: 2

Views: 130

Answers (3)

David W.
David W.

Reputation: 107040

From the Perldoc of Archive::Extract:

$ae->files

This is an array ref holding all the paths from the archive. See extract() for details.

It's quite common for methods to return not arrays and hashes, but references to them. It's also quite common for methods to take references to arrays and hashes as arguments. This is because less data has to be passed back and forth between the method and your call.

You can do this:

for my $file ( @{ $ae->files } ) {
    print "$file\n";
}

The @{...} dereferences the reference and makes it into a simple array. And yes, you can put method calls that return an array reference in the @{...} like I did.

As already mentioned, a very helpful package is Data::Dumper. This can take a reference and show you the data structure contained therein. It also will tell you if that data structure represents a blessed object which might be a clue that there is a method you can use to pull out the data.

For example, imagine an object called Company. One of the methods might be $company->Employees which returns an array reference to Employee objects. You might not realize this and discover that you get something like ARRAY{0x7fd5c22f7cd8) returned, pushing this through Data::Dumper might help you see the structure:

use Data::Dumper;
use Feature qw(say);

use Company;

[...]

@employee_list =  $company->Employees;

# say join "\n", @employee_list;   #Doesn't work.
say Dumper @employee_list;

This might print:

 $VAR = [
    {
        FIRST => 'Marion',
        LAST  => 'Librarian',
        POSITION => 'Yes Man',
    }  Employee,
    {
        FIRST => 'Charlie',
        LAST  => 'australopithecus`,
        POSITION => 'Cheese Cube Eater'
    }  Employee,
]

Not only do you see this is an array of hash references, but these are also objects Employee too. Thus, you should use some methods from the Employee class to parse the information you want.

use Feature qw(say);
use Company;
use Employee;

[...]
for my $employee ( @{ $company->Employees } ) {
    say "First Name: " . $employee->First;
    say "Last Name: " . $employee->Last;
    say "Position: " . $employee->Position;
    print "\n";
}

Upvotes: 1

Gilles Quénot
Gilles Quénot

Reputation: 185209

Try doing this :

use Data::Dumper;
print Dumper @files;

That way, you will see the content of @files.

If you don't know how to process your data structure, paste the output of Dumper here

Upvotes: 0

andytech
andytech

Reputation: 211

$ae->files returns an array reference, not an array. Try this:

my $files = $ae->files;

for(@$files) {
   print "file : $_\n";
}

Upvotes: 6

Related Questions