Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

String assignment oddity

by writch (Sexton)
on Mar 01, 2018 at 21:38 UTC ( #1210196=perlquestion: print w/replies, xml ) Need Help??

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

I have some code I'm working with which had the assignment of a base PDF file in a giant 'if elsif' block. It was assigning a different base PDF for form filling using CAM::PDF based on what kind of form it was, and what state we were using. Let's say they were contracts, of two types, and there were two states, so the block went something like this:
if ($type eq 'A'){ if ($state eq 'GA'){ $form{source} = 'files/blanks/state/GA/A/contract.pdf'; }elsif($state eq 'TX'){ $form{source} = 'files/blanks/state/TX/A/contract.pdf'; } elsif ($type eq 'B'){ if ($state eq 'GA'){ $form{source} = 'files/blanks/state/GA/B/contract.pdf'; }elsif($state eq 'TX'){ $form{source} = 'files/blanks/state/TX/B/contract.pdf'; } }
This worked flawlessly, but it could be more elegant. I wanted this:
$form{source} = "files/blanks/state/$state/$type/contract.pdf";
I'm printing out the $form{source} value in a log, but if I reassign the value with the latter statement, though it looks identical to me in the log, the file doesn't open correctly. I have traced this through to line 384 in CAM::PDF ( where it tests for $self->_startdoc(). Even though the content loaded is identical, $self->_startdoc() returns undef if I assign the source via the simple assignment method and 1 if it was via the if/else method.

Replies are listed 'Best First'.
Re: String assignment oddity
by syphilis (Bishop) on Mar 01, 2018 at 22:28 UTC
    $form{source} = "files/blanks/state/$state/$type/contract.pdf";

    Are you sure you haven't coded it as:
    $form{source} = 'files/blanks/state/$state/$type/contract.pdf';
    That would explain the failure.

Re: String assignment oddity
by Eily (Monsignor) on Mar 02, 2018 at 14:44 UTC

    Well I don't see anything in your code that would explain how $form{source} would look the same but give a different result. I do see that there is no "else", are you sure that you never fall in those cases? You could add else { die "This shouldn't happen" } just to be 100% sure. Also rather than print the values, you can use Data::Dump (or Data::Dumper with $Data::Dumper::Useqq) to see exactly what is in the string (eg: make invisible chars explicit). You can also let perl itself check if the two strings are identical, with the ^ to show exactly where the difference is:

    my $form_source = "files/blanks/state/$state/$type/contract.pdf"; die pp $form_source ^ $form{source} unless $form_source eq $form{sourc +e}; # pp from Data::Dump

    If all of this fails, you'll have to show more code.

Re: String assignment oddity
by writch (Sexton) on Apr 17, 2018 at 15:19 UTC
    Ok, I have found the fix. I'm not sure I understand what is going on under the hood, but the fix is to use the Encode library and instead of assigning it directly as such:

    $x = "files/$state/$type/thing.pdf"

    I use the results of encode to assign it instead:

    $x = encode('UTF-8', "files/$state/$type/thing.pdf", Encode::FB_CROAK);

    Tracing through the CAM::PDF code showed the data in the success path was looking like straight hex (AFDDECBB), while in the failure path it was showing as such: (\x{af}\x{dd}\x{ec}\x{bb}).

    Humans can't see any difference between $x, but perl sees something really different.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1210196]
Approved by Laurent_R
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (2)
As of 2020-10-25 06:26 GMT
Find Nodes?
    Voting Booth?
    My favourite web site is:

    Results (249 votes). Check out past polls.