0

Is it possible to use Perl's push() function on an array inside a hash?

Below is what I believe to be the offending part of a larger program that I am working on.

my %domains = ();
open (TABLE, "placeholder.foo") || die "cannot read domtblout file\n";
while ($line = <TABLE>)
{
    if (!($line =~ /^#/))                                                                 
    {
            @split_line = split(/\t/, $line);                                              # splits on tabs - some entries contain whitespace
        if ($split_line[13] >= $domain_cutoff)
        {
            push($domains{$split_line[0]}[0], $split_line[19]);                    # adds "env from" coordinate to array
            push($domains{$split_line[0]}[1], $split_line[20]);                    # adds "env to" coordinate to array
            # %domains is a hash, but $domains{identifier}[0] and $domains{$identifier}[1] are both arrays
            # this way, all domains from one sequence are stored with the same hash key, but can easily be processed iteratively
        }

    }

}

Later I try to interact with these arrays using

for ($i = 0, $i <= $domains{$identifier}[0], $i++)
        {
            $from = $domains{$identifier}[0][$i];
            $to = $domains{$identifier}[1][$i];
            $length = ($to - $from);
            $tmp_seq =~ /.{$from}(.{$length})/;
            print("$header"."$1");
        }

but it appears as if the arrays I created are empty.

If $domains{$identifier}[0] is an array, then why can I not use the push statement to add an element to it?

5
  • 1
    I'd recommend that you use strict; use warnings; at the top of your program. Commented Nov 30, 2015 at 20:21
  • Yes you need an array not a reference, see perldoc, for example push @{ $domains{$identifier}[0] }, .. ) Commented Nov 30, 2015 at 20:22
  • Yeah, I understand that I need an array not a reference, but I don't understand your suggested syntax. Do you mean push(@{$domains{$split_line[0]}[0]}, $split_line[19]) ? Commented Nov 30, 2015 at 20:32
  • I think there is a better explanation in perldsc Commented Nov 30, 2015 at 20:33
  • Thanks, I think that solved my problem - but I won't know until I can test the whole thing (turns out I have a second problem - the supposedly machine-readable data that I accept as input is whitespace delimited for some reason, so I need to deal with that before I can test overall functionality) Commented Nov 30, 2015 at 20:40

1 Answer 1

4

$domains{identifier}[0] is not an array.
$domains{identifier}[0] is an array element, a scalar.
$domains{identifier}[0] is a reference to an array.

If it's

@array

when you have an array, it's

@{ ... }

when you have a reference to an array, so

push(@{ $domains{ $split_line[0] }[0] }, $split_line[19]);

References:

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.