in reply to Cannot work on second file after reading first file.

Hi all,

coming home and seeing that this thread is growing I really get curious about what the problem is. 1straw seems to be a nice guy. So, I took the corrected program, created the directories addressed and put the data to the files.

After the first run I see the same weird result as 1straw.

So I follow the advice of davido who was giving the hint that it would be intersting to see what is slurped by the first getline in the relevant function. Inserted a use Data::Dumper; to the friends at the beginning of the script and changed the line

$csv ->getline ($fh);

into

my $header = $csv ->getline ($fh); print Dumper(\$header), "\n";

Another run showed the following output:

$VAR1 = \[ '# de tienda', ' tipo', ' ubicacion', 'li', 'location1', 'li', 'location2', 'li', 'location3', 'li', 'location4', 'li', 'location5', 'li', 'location6', 'li', 'location7', 'ff', 'location8', 'ff', 'location9', 'ff', 'location10', 'li', 'location11', 'ff', 'location12', 'ff', 'location13', 'ff', 'location14', 'ff', 'location15', 'li', 'location16', 'li', 'location17', 'ff', 'location18', 'ff', 'location19', 'ff', 'location20', 'ff', 'location21', 'li', 'location22', 'li', 'location23', 'ff', 'location24', 'ff', 'location25', 'ff', 'location26', 'ff', 'location27' ];

Uuuuuppsss, what is that? The whole file is slurped as one line. How can this be? What is the line seperator? Oh, there is no explicit definition! So, what is taken? I looked at the docs: Ahhh, the default seems to be the special variable $/. Oh, I've seen that variable in the script. Looking around I found this code in open_po:

open ($po_data, '<', $edi_file) or die "Could not open the file '$ed +i_file' $!\n"; undef $/; @po_array = split (/\~/, <$po_data>);

Oh, oh, you've changed a GLOBAL variable which changes the semantics of Text::CSV. (Search for "Global variables are bad" in Perlmonks ;-) )

So, a simple proove if this is the culprit. Put a local in front of it:

local $/ = undef;

and the next run shows that it's found.

Conclusion: davido gave the right hint but you seem not to put a print statement to the header gathering line which gave definitely the right hint. Changing global variables without localisation is risky. Don't localize, use CPAN modules doing what you like, e.g. File::Slurp. Use Data::Dumper as often as possible when you want to print debug lines. You're freed from thinking about what is stored to a variable.

Hope, we all could help you.

UPDATE: Argggghhh, this is the problem here: When you write a long answer, it can happen that someone is answering meanwhile. After looking at the results of my post I've seen that the right hints were given meanwhile. So, a ++ to those who were faster. :-)

Best regards
McA

Replies are listed 'Best First'.
Re^2: Cannot work on second file after reading first file.
by davido (Cardinal) on Feb 28, 2014 at 19:44 UTC

    That's exactly why I wanted to print "(@{$head})". It would tell me if $head contained stuff that shouldn't be there. The OP told me the following, "When I ran the script it printed: Field names detected: (# de tienda  tipo  ubicacion". I should have known -- because he didn't show me the closing paren ')' -- that his report to us was incomplete, and should have suspected that it lacked exactly the piece of information we were looking for.

    That doesn't excuse my not having seen "undef $/" earlier in the script, but had he reported the full output, or had I noticed that his report was incomplete, it would have led us to look for the modification of $/ sooner even though it was at first not noticed.


    Dave


      Hi Dave:

      I still don't understand what went wrong when I followed your instructions. I did mention the odd open parenthesis "(" without a closing parenthesis, but that's definitely all that was outputed. I just tried again w/ undef $/; and I can confirm (Li Stores: and FF Stores was the original output before implementing your code, it was still there afterward, but I didn't think it was important to mention):
      x@y:~/example$ perl example Field names detected: (# de tienda tipo ubicacion Li stores: FF Stores: x@y:~/example$

      I post this out of curiosity & to avoid making the same mistake in the future

      Thank you for your help, I really appreciate the time you took to help me figure this out!!

      1straw

      After seeing the output of the first line it was so obvious in combination that we've seen $/. But without that I would have read over this piece of code many times without seeing the problem.

      But the next time my presented solution will be a one-liner and not a whole story to see myself being late in the thread... ;-)

      Best regards
      McA

Re^2: Cannot work on second file after reading first file.
by 1straw (Novice) on Feb 28, 2014 at 20:01 UTC

    Thank you for the long answer McA! I will look into File::Slurp as well. I hope to continue learning and avoid these silly errors. I was aware that global variables were a bad idea, I just didn't realize I was changing $/ globally. I have very little programming experience in general, and about 1 week experience with Perl :P

    Thanks again!

      Hi 1straw,

      you're welcome!

      IMHO it's outstanding how you come back to your thread and react on the comments and advices given. That happens not too often. And I'm pretty sure this is the reason why you got help from all directions.

      I wish you much fun with programming in Perl.

      Best regards
      McA


        Thank you McA:

        I hope I can learn enough to someday return the help given!