كيف يمكنني استخدام قيمة متغير كاسم متغير بيرل؟ [مكرر

StackOverflow https://stackoverflow.com/questions/1726363

سؤال

هذا السؤال لديه بالفعل إجابة هنا:

آسف على كل هذه الأسئلة السخيفة، لقد تم توجيهها إلى برمجة بيرل وأجدها من الصعب حقا التفكير مثل برنامج Perl Programmer.

سؤال سخيف لهذا اليوم: أقوم بتحميل ملف محدد الأنابيب في علامة تجزئة باستخدام حقل معرف المفتاح، مثل ذلك

#open file

my %hash;
while (<MY_FILE>) {
    chomp;

    my ($id, $path, $date) = split /\|/;

    $hash{$id} = {
        "path" => $path,
        "date" => $date
    };
}

ومع ذلك، هناك عدة مرات، عندما أحتاج فعليا إلى المفتاح لتكون المسار لأنه، لأي سبب من الأسباب (وليس، لا يمكن تغييره) هو المعرف ليس فريدا، لذلك كان لدي فكرة مشرقة أنني أستطيع وضعها كل شيء في روتين فرعي وتمرير اسم المتغير لاستخدامه كمفتاح لذلك، كيندا مثل ذلك:

load_hash("path");

sub load_hash {
    my $key = shift;

    #do stuff, and then in while loop
    $hash{${$key}} = #and so on
}

ولكن في PERLDB X $ {$ key} هو دائما UNDEF، على الرغم من أن X $ {path} يطبع القيمة في مسار $.

هل هناك طريقة للقيام بما أحاول؟

تيا

هل كانت مفيدة؟

المحلول

شيء من هذا القبيل؟

use Carp 'confess';

sub load_hash {
    my $key = shift;

    # ...

    while (...) {
        # ...
        my %line;  # important that this is *inside* the loop
        @line{qw (id path date)} = split /\|/;
        confess "BUG: unknown key '$key'"  unless exists $line{$key};  # error checking
        $hash{$line{$key}} = \%line;
        delete $line{$key};  # assuming you don't want the key value duplicated
    }
}

نصائح أخرى

أنت تحاول استخدام "المراجع الرمزية". إذا كانت لديك مشكلة وتعتقد أن "مهلا، سأحل هذا بمراجع رمزية" لديك الآن مشكلتان.

أولا، فإنها تعمل فقط على العالم. لقد أعلنت $path كمعجم (مرئي فقط في الكتلة التي تم إعلانها) وبالتالي لا يمكن تحميل Load_Path. لا، لا تجعل $path عالمي.

ثانيا، يربط الرمزي إنشاء رمز السباغيتي. Globals سيئة بما فيه الكفاية. يمكن الوصول إليها في أي مكان وفي أي وقت من قبل أي شيء. مع مرجع رمزي إلى عالم عالمي، لا يمكنك حتى معرفة أي عالمي يتم الوصول إليه. هذا يجعل من المستحيل تتبع ما قد يغير ما. هذا هو السبب strict يحولهم. شغله strict واتركها حتى تعرف متى يجب عليك إيقاف تشغيلها.

أنا لست متأكدا تماما ما تحاول إنجازه، لكن يبدو أن هذا جيد.

my %hash;
while (<MY_FILE>) {
    chomp;

    my ($id, $path, $date) = split /\|/;

    $hash{$path} = {
        "path" => $path,
        "date" => $date
    };
}

ولكن من المحتمل أنك نقل تحليل الخط إلى وظيفة وترك تعيين التجزئة للحلقة الرئيسية. تحليل الخط هو جزء واضح من المنطق ويمكن فصله تماما عن تعيين السطر إلى ملف التجزئة. علامة جيدة هي ذلك %hash لا يجب أن يكون عالميا.

my %hash;
while (<MY_FILE>) {
    my $line = parse_line($_);

    my $id = $line->{path};
    $hash{$id} = $line;
}


my @fields = qw(id path date);
sub parse_line {
    my $line = shift;
    chomp $line;

    my %data;
    # This is assigning to a hash slice.  Look it up, its handy.
    @data{@fields} = split m{\|}, $line;

    return \%data;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top