Problemas con matrices en Perl

I am new to Perl and having some difficulty with arrays in Perl. Can somebody will explain to me as to why I am not able to print the value of an array in the script below.

$min = 999;
$LogEntry = '';
foreach $item (1, 2, 3, 4, 5)
  $min = $item if $min > $item;
  if ($LogEntry eq '') {
    push(@sum,"1"); }
    print "debugging the IF condition\n";
print "Array is: $sum\n";
print "Min = $min\n";

La salida que obtengo es:

debugging the IF condition
debugging the IF condition
debugging the IF condition
debugging the IF condition
debugging the IF condition
Array is:
Min = 1

¿No debería conseguir Array is: 1 1 1 1 1 (5 times). Can somebody please help? Thanks.

preguntado el 09 de marzo de 12 a las 15:03

There must be some code missing, there is nothing that would cause $logEntry to change from an empty string and the debugging message will always be printed as it is outside the if braces. -

8 Respuestas

Necesitas dos cosas:

use strict;
use warnings;

at which point the bug in your code ($sum en lugar de @sum) should become obvious...

respondido 09 mar '12, 15:03

Regardless of fixing this problem specifically, using strict and warnings like Alnitak says should pretty much be second nature. Always do it. - Mike

$sum is not the same variable as @sum.

In this case you would benefit from starting your script with:

use strict;
use warnings;

Estricto forces you to declare all variables, and warnings gives warnings..

In the meantime, change the first line to:

@sum = ();

and the second-to-last line to:

print "Array is: " . join (', ', @sum) . "\n";

Vea únete.

respondido 09 mar '12, 15:03

Tiene que ser my @sum=(); with strict. - dgw

As others have noted, you need to understand the way Perl uses sigils ($, @, %) to denote data structures and the access of the data in them.

You are using a scalar sigil ($), which will simply try to access a scalar variable named $sum, that has nothing to do with a completely distinct array variable named @sum - and you obviously want the latter.

What confuses you is likely the fact that, once the array variable @sum exists, you can access individual values in the array using $sum[0] syntax, but here the sigil+braces ($[]) act as a "unified" syntactic constract.

The first thing you need to do (after using strict and warnings) is to read the following documentation on sigils in Perl (aside from good Perl book):

The best summary I can give you on the syntax of accessing data structures in Perl is (quoting from my older comment)

  • the sigil represents the amount of data from the data structure that you are retrieving ($ of 1 element, @ for a list of elements, % for entire hash)

  • whereas the brace style represent what your data structure is (square for array, curly for hash).

    As a special case, when there are NO braces, the sigil will represent BOTH the amount of data, as well as what the data structure is.

Please note that in your specific case, it's the last bullet point that matters. Since you're referring to the array as a whole, you won't have braces, and therefore the sigil will represent the data structure type - since it's an array, you must use the @ sigilo.

contestado el 23 de mayo de 17 a las 12:05

Usted push the values into the array @sum, then finish up by printing the scalar $sum. @sum y $sum son dos completamente independiente variables. If you print "@sum\n" instead, you should get the output "11111".

respondido 09 mar '12, 15:03

print "Array is: $sum\n";

will print a non-existent scalar variable called $sum, not the array @sum and not the first item of the array.

If you 'use strict' it will flag the user of un-initialized variables like this.

respondido 09 mar '12, 15:03

You should definitly add use strict; y use warnings; to your script. That would have complained about the print "Array is: $sum\n"; line (among others).
And you initialize an array with my @sum=(); no con my $sum=();

respondido 09 mar '12, 15:03

Like CFL_Jeff mentions, you can't just do a quick print. Instead, do something like:

print "Array is ".join(', ',@array);

respondido 09 mar '12, 15:03

Actually, you can interpolate an array into the string: print "Arr: @array\n";. Won't look as pretty by default, of course - DVK

Not as pretty, but still worth noting - thanks for the correction. - Mike

Still would like to add some details to this picture. )

See, Perl is well-known as a Very High Level Language. And this is not just because you can replace (1,2,3,4,5) con (1..5) y obtener el mismo resultado.

And not because you may leave your variables without (explicitly) assigning some initial values to them: my @arr es tan bueno como my @arr = ()y my $scal (en lugar de my $scal = 'some filler value') may actually save you an hour or two one day. Perl is usually (with use warnings, yes) good at spotting undefined values in unusual places - but not so lucky with 'filler values'...

The true point of VHLL is that, in my opinion, you can express a solution in Perl code just like in any human language available (and some may be even less suitable for that case).

Don't believe me? Ok, check your code - or rather your set of tasks, for example.

Need to find the lowest element in a array? Or a sum of all values in array? List::Util module is to your command:

use List::Util qw( min sum );
my @array_of_values = (1..10);

my $min_value     = min( @array_of_values );
my $sum_of_values = sum( @array_of_values );

say "In the beginning was... @array_of_values";
say "With lowest point at $min_value"; 
say "Collected they give $sum_of_values"; 

Need to construct an array from another array, filtering out unneeded values? grep is here to save the day:

@filtered_array = grep { $filter_condition } @source_array;

See the pattern? Don't try to code your solution into some machine-codish mumbo-jumbo. ) Find a solution in your own language, then just find means to translate THAT solution into Perl code instead. It's easier than you thought. )

Disclaimer: I do understand that reinventing the wheel may be good for learning why wheels are so useful at first place. ) But I do see how often wheels are reimplemented - becoming uglier and slower in process - in production code, just because people got used to this mode of thinking.

respondido 10 mar '12, 00:03

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.