Почему Perl "хэш списков" делает это? - PullRequest
1 голос
/ 09 июня 2009

У меня есть хэш списков, который не заполняется.

Я проверил, что блок в конце, который добавляет к хешу, на самом деле вызывается на входе. Следует либо добавить одноэлементный список, если ключ не существует, либо нажать на заднюю часть списка (на который указывает правая клавиша), если он существует.

Я понимаю, что GOTO безобразен, но я прокомментировал это, и это не имеет никакого эффекта.

Проблема в том, что при вызове printhits ничего не печатается, как будто в хэше нет значений. Я также попробовал каждый (% genomehits), без игры в кости.

СПАСИБО!

#!/usr/bin/perl
use strict;
use warnings;

my $len = 11; # resolution of the peaks

#$ARGV[0] is input file
#$ARGV[1] is call number
# optional -s = spread number from call
# optional -o specify output file name
my $usage = "see arguments";
my $input = shift @ARGV or die $usage;
my $call = shift @ARGV or die $usage;
my $therest = join(" ",@ARGV) . " ";
print "the rest".$therest."\n";
my $spread = 1;
my $output = $input . ".out";
if ($therest =~ /-s\s+(\d+)\s/) {$spread = $1;}
if ($therest =~ /-o\s+(.+)\s/) {$output = $1;}

# initialize master hash
my %genomehits = ();

foreach (split ';', $input) {
    my $mygenename = "err_naming";
    if ($_ =~ /^(.+)-/) {$mygenename = $1;}

    open (INPUT, $_);
    my @wiggle = <INPUT>;

    &singlegene(\%genomehits, \@wiggle, $mygenename);

    close (INPUT);
}

&printhits;

#print %genomehits;
sub printhits {
    foreach my $key (%genomehits) {
        print "key: $key , values: ";
    foreach (@{$genomehits{$key}}) {
        print $_ . ";";
    }
    print "\n";
    }
}

sub singlegene {
 # let %hash be the mapping hash
 # let @mygene be the gene to currently process
 # let $mygenename be the name of the gene to currently process

    my (%hash) = %{$_[0]};
    my (@mygene) = @{$_[1]};
    my $mygenename = $_[2];

    my $chromosome;
    my $leftbound = -2;
    my $rightbound = -2;

    foreach (@mygene) {
        #print "Doing line ". $_ . "\n";

        if ($_ =~ "track" or $_ =~ "output" or $_ =~ "#") {next;}

        if ($_ =~ "Step") {
            if ($_ =~ /chrom=(.+)\s/) {$chromosome = $1;}
            if ($_ =~ /span=(\d+)/) {$1 == 1 or die ("don't support span not equal to one, see wig spec")};
            $leftbound = -2;
            $rightbound = -2;
            next;
        }

        my @line = split /\t/, $_;
        my $pos = $line[0];
        my $val = $line[-1];

        # above threshold for a call
        if ($val >= $call) {
            # start of range
            if ($rightbound != ($pos - 1)) {
                $leftbound = $pos;
                $rightbound = $pos;
            }
            # middle of range, increment rightbound
            else {
                $rightbound = $pos;
            }

            if (\$_ =~ $mygene[-1]) {goto FORTHELASTONE;}
        }
        # else reinitialize: not a call
        else {
            FORTHELASTONE:
            # typical case, in an ocean of OFFs
            if ($rightbound != ($pos-1)) {
                $leftbound = $pos;
            }
            else {
            # register the range
                my $range = $rightbound - $leftbound;
                for ($spread) {
                    $leftbound -= $len;
                    $rightbound += $len;
                }
                #print $range . "\n";

                foreach ($leftbound .. $rightbound) {
                    my $key = "$chromosome:$_";
                    if (not defined $hash{$key}) {
                        $hash{$key} = [$mygenename];
                    }
                    else { push @{$hash{$key}}, $mygenename; }
                }
            }
        }

    }

}

Ответы [ 2 ]

4 голосов
/ 09 июня 2009

Вы передаете ссылку на %genomehits функции singlegene, а затем копируете ее в новый хэш, когда выполняете my (%hash) = %{$_[0]};. Затем вы добавляете значения к %hash, который исчезает в конце функции.

Чтобы исправить это, используйте ссылку непосредственно с обозначением стрелки. Э.Г.

my $hash = $_[0];
...
$hash->{$key} = yadda yadda;
2 голосов
/ 09 июня 2009

Я думаю, что это такая строка:

my (%hash) = %{$_[0]};

Вы передаете ссылку, но это утверждение делает копию вашего хэша. Все дополнения, которые вы вносите в singlegene, теряются при вашем возвращении.

Оставьте его как ссылку на хэш, и он должен работать.

PS - Data :: Dumper - ваш друг, когда большие структуры данных не работают должным образом. Я бы посыпал некоторые из них в вашем коде ...

use Data::Dumper; print Dumper \%genomehash;

...