in reply to Re: Script works in XP but not Ubuntu?
in thread Script works in XP but not Ubuntu?

Within-script solution: use lib '.';

In this case script will search libraries in cwd. If you want it to search them in the same directory as script itself you better use:

use FindBin qw($Bin); use lib "$Bin";

Replies are listed 'Best First'.
Re^3: Script works in XP but not Ubuntu?
by BassKozz (Initiate) on Apr 02, 2009 at 01:41 UTC
    Thanks for all the feedback "use lib '.';" seems to have done the trick... but now I have another problem with this script, it seems to keep looping on the following function:

    #@data = SplitCSVLine($csv_line); sub SplitCSVLine { my ($line) = @_; my ($value, @data); while(1) { last if($line =~ /^\s*$/); if($line =~ /^[^\"]/) { $line =~ s/(.*?)(,|$ )//x; $value = $1; } else { $line =~ s/\"((\"\"|[^\"])*)\"(,|$ )//x; $value = $1; $value =~ s/\"\"/\"/g if defined $value; } push @data, $value; } return @data; }

    I can't figure out why, the code that calls this function is:

    sub GetStyleCodesMap { my @csv_lines = chrtoolbox::MyCat('style_codes.csv'); my $line_num = 0; foreach my $line (@csv_lines) { $line_num++; next if($line_num == 1); #skip the header last if($line eq "\n"); #done reading the mapping @data = SplitCSVLine($line);

    Any ideas?
    Thanks again for all the help,
    -BassKozz

      I copied your subroutine SplitCSVLine into a different file and put the following before it

      #!/usr/bin/perl use strict; use warnings; my @res= SplitCSVLine('123,hubba hubba,bla fasel,hell'); print ':',join":",@res,":\n";

      When I started the program, the result was:

      :123:hubba hubba:bla fasel:hell::

      This suggests two things: 1) For some input values it works without getting into an endless loop. 2) It returns an empty field after the last (i.e. the :: after 'hell' is an empty string), so it probably isn't working completely as intented.

      After looking at the regular expressions I also tried the string '123,"hubba" ,bla fasel,help' and this got into an endless loop. The problem is that the second s/// regex doesn't allow any spaces between a string in double quotes and the following comma. This could be fixed with changing that regexp to

      $line =~ s/\"((\"\"|[^\"])*)\"\s*(,|$ )//x;

      But is that all or did I overlook another case that leads to an endless loop? I don't know. A much better way to deal with this bug would be to substitute your subroutine with a module like Text::CSV that is much better tested and probably takes care of anything that could be thrown at it.

      By the way, it would have been much easier for you to find the problematic case than it was for me to analyze the subroutine. Just print out any values delivered to the subroutine (i.e. insert print "|$line|\n"; after the first line inside the subroutine). The last value you see printed should be the one leading to the endless loop

      You could even add print statements inside the while loop to see how $line changes and ultimately how it doesn't change anymore.

      The subroutine also goes into an infinite loop if the input string has unbalanced quotes. Check what you have in style_codes.csv - probably something not quite right there.

      There are some very good modules for reading CSV files which would handle such errors without going into an infinite loop. They can't fix corrupt data, but they can give a useful error message. You might try Text::CSV::Simple or search CPAN for CSV for other options.

        I would say the infinite loop never ends due to faulty logic :)