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

What I want to happen is for a text file (named pi.txt) to be read in and then having its contents broke down into an array @numberMutation. Then, for each element in the @numberMutation array, I want it to compare that element to each element of the @organism array and change the element if the condition is met (if the current element is smaller than the mutation). I am not sure what I have done wrong and would be greatful for any assistance :D Thx!
#!/usr/bin/perl -w #filename: myMutator.pl use strict; our (@organism,@numberMutation,$currentGene,$currentMutation,$someGene +,$thisMutate,$i); @organism = (1,1,1,1,1,1,1,1,1); open(FILE,"myFiles/pi.txt"); while (<FILE>) { chomp; @numberMutation = split(/\C/,$_); } foreach $currentMutation(@numberMutation) { $i = 0; foreach $currentGene(@organism) { if ($currentGene < $currentMutation) { $organism[$i] = $currentMutation; $i++; } } } foreach $someGene(@organism) { print "${someGene}\n"; } foreach $thisMutate(@numberMutation) { print "${thisMutate}\n"; }
UPDATE: Thx to everyone for all the help! It works now! :D Thx a bunches!!!! :D

Replies are listed 'Best First'.
Re: Arrays not being manipulated
by trammell (Priest) on Jan 01, 2005 at 04:59 UTC
    A few comments, in no particular order:
    • You should always check the return value of open(), e.g.:
      open(FILE,'myfile') || die "Couldn't open 'myfile': $!";
    • You don't need to declare all of those variables as globals at the top of your script.
    • Hard to say since I don't know the formatting of pi.txt, but your split() looks suspect. Maybe you want to split on ' ' or //?
    • Those loops at the end can be shortened considerably:
      print "@organism\n"; print "@numberMutation\n";
      Those loops at the end can be shortened considerably:
      Not quite. Assume that @a=(1,2,3). Doing it your way will produce "123\n". Doing it the OPs way will produce "1\n2\n3\n". As for me, I'd do it thusly:
      print join("\n",@organism), "\n"
      or even
      { local $,="\n"; print "@organism\n" }

      thor

      Feel the white light, the light within
      Be your own disciple, fan the sparks of will
      For all of us waiting, your kingdom will come

        Not quite. Assume that @a=(1,2,3). Doing it your way will produce "123\n"

        Not quite.
        @a=(1,2,3); print "@a";
        will produce "1 2 3";
Re: Arrays not being manipulated
by William G. Davis (Friar) on Jan 01, 2005 at 06:59 UTC

    Beyond what was already mentioned:

    @numberMutation = split(/\C/,$_);

    Are you sure you don't mean to use push() there instead of assignment? Assignment assigns a new list to an array (that is, it replaces the current list with another):

    @array = qw(one two three); # @array contains "one", "two" and "three" @array = qw(four five); # @array now contains just "four" and "five"

    push() adds scalars to the end of an array, like this:

    @array = qw(one two three); # @array now contains "one", "two" and "three" push(@array, qw(four five)); # @array now contains "one", "two", "three", "four" and "five"

    Also, why are you splitting $_ on \C? The \C metasymbol means match one byte exactly, not the capital letter "C" or a carriage return or anything else. If you want to match "C", the letter, then just get rid of the backslash. If you want to match a carriage return, then binmode() the file handle before reading from it and use \015 instead of \C.

      Because, I plan to write another perl script that will calculate pi and write it to a file. The current file being used, pi.txt, has the following formating that will eventually match the other script: 31415926535897932384626433832 So I need the string to be broken down into single values (like 3 or just 1 or just 4) in order to do the comparisons. If I don't declare all those variables as being global, Perl refuses to compile the script :/

        Regardless, split(/\C/, $_) is still wrong. You want split(//, $_) instead. That will split "314" up into "3", "1", and "4" like you want.

        Also, you don't need to declare them as global with our. Declare varaibles with my instead, when you first use them:

        #!/usr/bin/perl -w #filename: myMutator.pl use strict; my $file = shift || "myFiles/pi.txt"; open(FILE, "< $file") or die "Couldn't open $file: $!"; my @numberMutation; while (<FILE>) { chomp; push(@numberMutation, split(//, $_)); } my @organism = (1,1,1,1,1,1,1,1,1); foreach my $currentMutation (@numberMutation) { my $i = 0; foreach my $currentGene (@organism) { if ($currentGene < $currentMutation) { $organism[$i] = $currentMutation; $i++; } } } foreach my $someGene (@organism) { print "$someGene\n"; } foreach my $thisMutate (@numberMutation) { print "$thisMutate\n"; }

        I'm still not quite sure what you're trying to do, but if the file only contains a single line, you can avoid using a loop to read from it and just do this:

        chomp(my $line = <FILE>); my @numberMutation = split(//, $line);
Re: Arrays not being manipulated
by nedals (Deacon) on Jan 01, 2005 at 20:08 UTC

    Restating...
    I want it to compare each element ($currentMutation) in the @numberMutation array to each element in the @organism array and set the @organism[$i] = $currentMutation if (@organism[$i] < $currentMutation)

    The @organism array is preset to all 1's.
    Given this logic, ALL the elements of @organism will always be set to the highest value of $currentMutation.

    I don't think that's what you want!?
    use strict; ## Simplified for testing my @numberMutation = (); while (<DATA>) { chomp; @numberMutation = split(//,$_); } my @organism = (1,1,1,1,1,1,1,1,1); foreach (@numberMutation) { my $currentMutation = $_; my $i = 0; foreach (@organism) { if ($_ < $currentMutation) { $organism[$i] = $currentMutation; $i++; } } } print "ORG: @organism\n"; ## prints ORG: 9 9 9 9 9 9 9 9 9 print "MUT: @numberMutation\n"; __DATA__ 31415926535897932384626433832
      Could you please explain to me why it is better to declare the variables with my instead of using our? Thx for all the help everyone :D