Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Perl multidimensional arrays with "use strict"

Reply
Thread Tools

Perl multidimensional arrays with "use strict"

 
 
Franck
Guest
Posts: n/a
 
      06-15-2004
Hi!

Little problem there. Can someone tell me what's the problem with
this? The first test below works while the second doesn't. I have to
use strict so I need to know why it doesn't work and what I have to do
to fix the problem in the second test. It complains when I put items
in the second dimension of the array..."Can't use string ("group 0")
as an ARRAY ref while "strict refs" in use at test.pl line 18."

Thx a lot!
Franck

#################################################
#FIRST TEST
$i = 0;
$j = 0;
$k = 0;

@data = ();

for ($i=0; $i<=3; $i++){
$data[$i] = "group $i";

for ($j=0; $j<=3; $j++){
$temp1 = $j+$i+10;
$data[$i][$j] = "user $temp1";

for ($k=0; $k<=3; $k++){
$temp2 = $k+100;
$data[$i][$j][$k] = " $temp2";
}
}
}

for ($i=0; $i<=3; $i++){
print "\n\n$data[$i] own: ";
for ($j=0; $j<=3; $j++){
print "\n $data[$i][$j] who have privilege ";
for ($k=0; $k<=3; $k++){
print "$data[$i][$j][$k],";
}
}
}
#################################################

#################################################
#SECOND TEST
use strict;
use warnings;


my $i = 0;
my $j = 0;
my $k = 0;

@::data = ();
my $temp1;
my $temp2;

for ($i=0; $i<=3; $i++){
$::data[$i] = "group $i";

for ($j=0; $j<=3; $j++){
$temp1 = $j+$i+10;
$::data[$i][$j] = "user $temp1";

for ($k=0; $k<=3; $k++){
$temp2 = $k+100;
$::data[$i][$j][$k] = " $temp2";
}
}
}

for ($i=0; $i<=3; $i++){
print "\n\n$::data[$i] own: ";
for ($j=0; $j<=3; $j++){
print "\n $::data[$i][$j] who have privilege ";
for ($k=0; $k<=3; $k++){
print "$::data[$i][$j][$k],";
}
}
}
#################################################
 
Reply With Quote
 
 
 
 
Paul Lalli
Guest
Posts: n/a
 
      06-15-2004
On Tue, 15 Jun 2004, Franck wrote:

> Hi!
>
> Little problem there. Can someone tell me what's the problem with
> this? The first test below works while the second doesn't. I have to
> use strict so I need to know why it doesn't work and what I have to do
> to fix the problem in the second test. It complains when I put items
> in the second dimension of the array..."Can't use string ("group 0")
> as an ARRAY ref while "strict refs" in use at test.pl line 18."
>
> Thx a lot!
> Franck
>
> #################################################
> #FIRST TEST

<code without strict snipped>

> #################################################
> #SECOND TEST
> use strict;
> use warnings;
>
>
> my $i = 0;
> my $j = 0;
> my $k = 0;
>
> @::data = ();


Why are you using a global variable? This isn't 'wrong' per say, but it
is unusual. You usually want a lexical variable, especially with
strictures enabled:

my @data;

> my $temp1;
> my $temp2;
>
> for ($i=0; $i<=3; $i++){
> $::data[$i] = "group $i";


Okay, here you are filling the array @data with text strings. Position 0
contains "group 0", position 1 contains "group 1", etc.

>
> for ($j=0; $j<=3; $j++){
> $temp1 = $j+$i+10;
> $::data[$i][$j] = "user $temp1";


Here you're suddenly deciding that @data no longer contains text strings,
and instead now contains references to arrays. Why? The error you're
rightly getting is telling you that $data[$i] contains the string "group
$i", which you are attempting to convert to an array reference.


>
> for ($k=0; $k<=3; $k++){
> $temp2 = $k+100;
> $::data[$i][$j][$k] = " $temp2";


Same problem. Assuming the above worked, $data[$i][$j] would contain the
text string "user 10" (for example). Now you're trying to use that string
as an array reference.


> }
> }
> }
>
> for ($i=0; $i<=3; $i++){
> print "\n\n$::data[$i] own: ";
> for ($j=0; $j<=3; $j++){
> print "\n $::data[$i][$j] who have privilege ";
> for ($k=0; $k<=3; $k++){
> print "$::data[$i][$j][$k],";
> }
> }
> }
> #################################################
>


I think it would be good for you to define what your goal is, rather than
defining what you think you have to do to obtain that goal. Using
symbolic references (which is the official term for what you're trying to
do here) is A Bad Idea, which is why it's disabled by use strict;. So,
what is it you *want* to do? Once you tell us that, we can help you
figure out the correct way of obtaining that goal.

Paul Lalli
 
Reply With Quote
 
 
 
 
Eric Bohlman
Guest
Posts: n/a
 
      06-15-2004
http://www.velocityreviews.com/forums/(E-Mail Removed) (Franck) wrote in
news:(E-Mail Removed) om:

> Little problem there. Can someone tell me what's the problem with
> this? The first test below works while the second doesn't. I have to
> use strict so I need to know why it doesn't work and what I have to do
> to fix the problem in the second test. It complains when I put items
> in the second dimension of the array..."Can't use string ("group 0")
> as an ARRAY ref while "strict refs" in use at test.pl line 18."


Because you've inadvertently created a symbolic reference instead of an
array of array references ("AoA") (which is how a multidimensional array is
implemented.

> #FIRST TEST
> $i = 0;
> $j = 0;
> $k = 0;
>
> @data = ();
>
> for ($i=0; $i<=3; $i++){
> $data[$i] = "group $i";


First time around, $data[0] eq 'group 0'

>
> for ($j=0; $j<=3; $j++){
> $temp1 = $j+$i+10;
> $data[$i][$j] = "user $temp1";


And this assignment actually works out to

${'group 0'}[0] = "user 10";

because it's using $data[0] as a symref, which is disallowed under strict.

I suspect you really want a multidimensional *hash* ("HoH") here rather
than an array. Reading perlreftut, perllol, and perldsc should set you in
the right direction.
 
Reply With Quote
 
thundergnat
Guest
Posts: n/a
 
      06-15-2004
Franck wrote:
> Hi!
>
> Little problem there. Can someone tell me what's the problem with
> this? The first test below works while the second doesn't. I have to
> use strict so I need to know why it doesn't work and what I have to do
> to fix the problem in the second test. It complains when I put items
> in the second dimension of the array..."Can't use string ("group 0")
> as an ARRAY ref while "strict refs" in use at test.pl line 18."
>
> Thx a lot!
> Franck
>


Well, very much like it is saying, you are trying to use a string as an
array ref. When you create lists of lists: $::data[$i][$j], the $i array
holds references to the arrays indexed by the $j variable. You can't
just arbitrarily assign strings to them, they are already in use as
array references.



> #################################################
> #SECOND TEST
> use strict;
> use warnings;
>
>
> my $i = 0;
> my $j = 0;
> my $k = 0;
>
> @::data = ();
> my $temp1;
> my $temp2;
>
> for ($i=0; $i<=3; $i++){
> $::data[$i] = "group $i";
>
> for ($j=0; $j<=3; $j++){
> $temp1 = $j+$i+10;
> $::data[$i][$j] = "user $temp1";
>
> for ($k=0; $k<=3; $k++){
> $temp2 = $k+100;
> $::data[$i][$j][$k] = " $temp2";
> }
> }
> }
>
> for ($i=0; $i<=3; $i++){
> print "\n\n$::data[$i] own: ";
> for ($j=0; $j<=3; $j++){
> print "\n $::data[$i][$j] who have privilege ";
> for ($k=0; $k<=3; $k++){
> print "$::data[$i][$j][$k],";
> }
> }
> }
> #################################################


I would rewrite this this way:

Since you are just using the indicies to calculate the various
parameters, you can just perform the calculations when you need them,
rather than precalculating them and storing them. Declare your variables
for the smallest scope necessary. Avoid using unnecessary temp
variables. I'm not sure why you were using a package variable (@::data),
it's not really wrong if you need the varible to be global, but you
should probably avoid it unless you definitely need the global scope.

You may be served better by a different data structure. Without knowing
more about what kinds of information you are storing, how much of it
there will be and how you need to retrieve it, it is difficult to say.

You might want to look at the perl docs about lists of lists.

perldoc perllol - or -

http://www.perl.com/doc/manual/html/pod/perllol.html




(Anyway, I doubt if this is what you really /wanted/, but it is
essentially what you were /trying/ to do.)


use strict;
use warnings;

my @data = ();

for my $i (0..3){
for my $j (0..3){
for my $k (0..3){
$data[$i][$j][$k] = $k+100;
}
}
}

for my $i (0..3){
print "\n\ngroup $i own: ";
for my $j (0..3){
print "\n user ",$j+$i+10,' who have privilege';
for my $k (0..3){
print ' ',$k+100,",";
}
}
}
 
Reply With Quote
 
thundergnat
Guest
Posts: n/a
 
      06-15-2004
thundergnat wrote:

>
> use strict;
> use warnings;
>
> my @data = ();
>
> for my $i (0..3){
> for my $j (0..3){
> for my $k (0..3){
> $data[$i][$j][$k] = $k+100;
> }
> }
> }
>
> for my $i (0..3){
> print "\n\ngroup $i own: ";
> for my $j (0..3){
> print "\n user ",$j+$i+10,' who have privilege';
> for my $k (0..3){
> print ' ',$k+100,",";
> }
> }
> }


Ummm. Make that:

use strict;
use warnings;

my @data = ();

for my $i (0..3){
for my $j (0..3){
for my $k (0..3){
$data[$i][$j][$k] = $k+100;
}
}
}

for my $i (0..3){
print "\n\ngroup $i own: ";
for my $j (0..3){
print "\n user ",$j+$i+10,' who have privilege';
for my $k (0..3){
print ' ',$data[$i][$j][$k],",";
}
}
}
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
casting pointers/arrays to multidimensional arrays Francesco C++ 2 11-06-2009 09:04 AM
Multidimensional arrays and arrays of arrays Philipp Java 21 01-20-2009 08:33 AM
Multidimensional arrays in Struts form? geclinke Java 1 06-18-2004 03:31 PM
Multidimensional arrays? anything else? d[ - - ]b ASP .Net 2 05-18-2004 12:17 PM
Cast to multidimensional arrays Jay Java 1 01-30-2004 04:27 PM



Advertisments