Perl: the Markov chain saw PerlMonks

### Arrays and Push

by viored (Novice)
 on Apr 03, 2014 at 04:35 UTC Need Help??
viored has asked for the wisdom of the Perl Monks concerning the following question:

So I'm using a module that requires an lower diagonal matrix. However, there seems to be some importance on how the matrix is defined. If I were to define the matrix like this
```\$distmatrix=[[] , [0.25], [0.25,0.5], [1,0.75,0.75]]
Everything works fine, however, when I define a matrix like this
```\$main::hd=[[]];
\$main::a = [0.25];
\$main::b = [0.25,0.5];
\$main::c = [1,0.75,0.75];
push @{main::hd}, [@main::a];
push @{main::hd}, [@main::b];
push @{main::hd}, [@main::c];
then I have an error. Whats the difference between the two? I need to add to my distance matrix every time step as it grows, so defining the distance matrix explicitly doensn't look like an option.

EDIT

I'm still at school, but I'll try your suggestions when I get home. The code I'm using does have strict on, but the error is with two modules that I'm using, or rather, the input I'm giving the module isn't what it expects (evidenced by a croak statement) When I run the following code
```#!/usr/bin/perl
#ex2
use warnings;
use strict;
sub clust;

\$main::hd=[[]];
\$main::a = [0.25];
\$main::b = [0.25,0.5];
\$main::c = [1,0.75,0.75];
push @{main::hd}, [@main::a];
push @{main::hd}, [@main::b];
push @{main::hd}, [@main::c];
\$main::hdt = 0.4;
&clust;
for (\$loop::i=0; \$loop::i<=3; \$loop::i++)
{
print \$clust::cluster_ids->[\$loop::i], "\n";
}
sub clust {
use Algorithm::Cluster::Thresh;
use Algorithm::Cluster qw/treecluster/;
\$clust::tree = treecluster(data=>\$main::hd, method=>'a');
\$clust::cluster_ids = \$clust::tree->cutthresh(\$main::hdt);
}
I get the error "memory allocation failure in treecluster" Which, after I read the module code comes from a croak statement if "!distmatrix" which I'm guessing means that if I input something that's not the correct kind of matrix, then it can't work. However, If I use the code
```#!/usr/bin/perl
#ex2
use warnings;
use strict;
sub clust;

\$main::hd=[[] , [0.25], [0.25,0.5], [1,0.75,0.75]];
\$main::hdt = 0.4;
&clust;
for (\$loop::i=0; \$loop::i<=3; \$loop::i++)
{
print \$clust::cluster_ids->[\$loop::i], "\n";
}
sub clust {
use Algorithm::Cluster::Thresh;
use Algorithm::Cluster qw/treecluster/;
\$clust::tree = treecluster(data=>\$main::hd, method=>'a');
\$clust::cluster_ids = \$clust::tree->cutthresh(\$main::hdt);
}
I get the desired output
```1
1
1
0
Sorry for being so vague, and I'll try your solutions tonight when I get home.

Replies are listed 'Best First'.
Re: Arrays and Push
by fullermd (Priest) on Apr 03, 2014 at 04:54 UTC

Well, for one thing,

```\$main::a = [0.25];
push @{main::hd}, [@main::a];

You never define an array @main::a (only an array ref \$main::a), so that's going to push nothing. All the explicit packages make it a little harder to read, too.

And if you fix it to \$main::a, it'll be pushing a ref to an array with one element, which element is an array ref, which isn't what you want either. You're kinda shotgunning syntax at the problem. What you probably want is something much simpler like

```@hd = ( [] );
\$a = [0.25]
\$b = [0.25, 0.5];
push @hd, \$a;
push @hd, \$b;
And if you fix it to \$main::a, it'll be pushing a ref to an array with one element, which element is an array ref, which isn't what you want either.

Actually,that is exactly what he wants and what both you and I have described. :) The element in the array ref is in fact a value and not another array.

```\$ cat pm1080886.pl
#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my @hd = ( [] );
my \$a = [0.25];
my \$b = [0.25, 0.5];
push @hd, \$a;
push @hd, \$b;

print Dumper(\@hd);

exit;

__END__
\$ ./pm1080886.pl
\$VAR1 = [
[],
[
'0.25'
],
[
'0.25',
'0.5'
]
];

It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.

Actually,that is exactly what he wants and what both you and I have described.

Not exactly. Just doing that sub would leave him doing a push @hd, [\$a]; construct, which would be the Wrong I described. He also needs to slay the Bracket Fairy that's sprinkling dust through the code to get the push \$hd, \$a; that you/we have there.

Re: Arrays and Push
by boftx (Deacon) on Apr 03, 2014 at 04:49 UTC

My immediate thought is that you want this instead since you have never defined the arrays but only array references (I am assuming that you are seeing an error because you have use strict; in your code):

```\$main::hd=[[]];
\$main::a = [0.25];
\$main::b = [0.25,0.5];
\$main::c = [1,0.75,0.75];
push @{\$main::hd}, \$main::a;
push @{\$main::hd}, \$main::b;
push @{\$main::hd}, \$main::c;

Edit: it would help a lot to see the actual error message(s) you are seeing.

Edit 2: corrected @{main::hd} to @{\$main::hd}.

Edit 3: In more general terms, now that I've had a little bit more Scotch, the overall problem appears to be that he does not full understand the correct syntax for de-referencing. OP defines array references, but is using them as arrays. If OP had used the correct syntax of @{\$array_ref} instead of @array_ref (when only \$array_ref is defined) then it would have worked as expected.

Understanding sigils, scope and context is crucial to understanding Perl. I think this person will be fine once this is grokked.

It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
Re: Arrays and Push
by bigj (Monk) on Apr 03, 2014 at 05:09 UTC
Instead of push @{main::hd}, [@main::a]; you either wanted to write push @{main::hd}, \$main::a; or push @{main::hd}, [@\$main::a]; If you had used use strict; use warnings Perl would have told you that @main::a is an undefined value. Only the scalar (reference to an array) \$main::a is defined by you (in line 2).

Greetings,
Janek

I suspect that he did in fact have use strict; in place and is seeing such an error message. I say this because there is little or no reason to ever use fully qualified variable names unless one does not fully understand how to use my \$variable (or our \$variable) when use strict; is in effect.

On a side-note, it is a pleasant surprise to see someone who knows about the "main" namespace. :)

It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.

Create A New User
Node Status?
node history
Node Type: perlquestion [id://1080886]
Approved by boftx
help
Chatterbox?
and monks are getting baked in the sun...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (6)
As of 2018-03-24 10:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
When I think of a mole I think of:

Results (298 votes). Check out past polls.

Notices?