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

Hi - I have a problem where sometimes this method will cause the script to fail with the error "Can't upgrade that kind of scalar at /usr/lib/perl5/site_perl/5.8.8/PDF/API2/Basic/PDF/Objind.pm line 150", This will always happen with the same source PDF in the same job. Basically I'm doing :
use strict; use PDF::API2; my $source_pdf = $ARGV[0]; my $dest_pdf = $ARGV[1]; my $pdf_d = PDF::API2->new(); my $pdf_s = PDF::API2->open($source_pdf); for ( my $pdf_page = 1 ; $pdf_page <= $pdf_s->pages ; $pdf_page++ ){ my $pdf_d_page = $pdf_d->page(); my $pdf_d_pageform = $pdf_d->importPageIntoForm($pdf_s, $pdf_page); my $pdf_d_gfx = $pdf_d_page->gfx; $pdf_d_gfx->formimage($pdf_d_pageform, 0, 0, 1); } $pdf_s->end(); $pdf_d->saveas($dest_pdf); $pdf_d->end();
except that there is a lot of other code and all of the above is in several other loops etc. There're a lot of source pdfs. The "$pdf_s->end();" will cause the error in the bad cases.

I'm afraid that I'm unable to supply the actual code or the source, problem pdfs.

While I can duplicate this 100% when it happens (perhaps with 1 in 100,000 source pdfs) with the actual script and I have isolated that the "$pdf_s->end()" is the problem line, I have not been able to replicate it in smaller test scripts using the same source pdfs yet. However I have found that if I replace the $pdf_s->end() with undef($pdf_s) everything seems to go perfectly in the production script with the problem source pdfs.

So I ask for your wisdom, Monks. Is replacing $pdf_s->end() as described a bad idea for some reason that I'm unaware of? Thanks.

Replies are listed 'Best First'.
Re: PDF::API2, $pdf->end
by johnny_carlos (Scribe) on Nov 04, 2011 at 20:09 UTC
    I may not be wise enough for commenting here, but no one else has so I guess it's better than nothing :)

    The code snippet looks good(to me), but you indicate that the real code is in "several other loops". Is it possible you are calling $pdf_s->end on a file that already had $pdf_s->end called on it?

    Is it possible that a particular pdf is causing the problem, have you kept track of the file names, and output the name of the current file when it crashes?

      Re "Is it possible you are calling $pdf_s->end on a file that already had $pdf_s->end called on it? ", no, afraid not.

      Re "Is it possible that a particular pdf is causing the problem, have you kept track of the file names, and output the name of the current file when it crashes? " yes, absolutely. After the fact I know what file has caused the problem and if I use the same script etc again on it (on it's own or with other source files) I get the same results. However I haven't found anything common with the problem source pdfs yet.

Re: PDF::API2, $pdf->end
by pvaldes (Chaplain) on Nov 04, 2011 at 20:09 UTC
    what is in the line 150?
      Here's the whole function that contains that line, with line 150 commented like "# LINE 150":
      sub release { my ($self, $force) = @_; my (@tofree); return($self) unless(ref $self); # delete stuff that we know we can, here if ($force) { foreach my $key (keys %{$self}) { push(@tofree,$self->{$key}); $self->{$key}=undef; delete($self->{$key}); } } else { @tofree = map { delete $self->{$_} } keys %{$self}; } while (my $item = shift @tofree) { my $ref = ref($item); if (UNIVERSAL::can($item, 'release')) # LINE 150 { $item->release($force); } elsif ($ref eq 'ARRAY') { push( @tofree, @{$item} ); } elsif (UNIVERSAL::isa($ref, 'HASH')) { release($item, $force); } } # check that everything has gone - it better had! foreach my $key (keys %{$self}) { # warn ref($self) . " still has '$key' key left after release. +\n"; $self->{$key}=undef; delete($self->{$key}); } }