2010-10-10 13 views

Odpowiedz

3

To całkowicie zależy od implementacji iteratora. Jeśli jedyną dostępną metodą jest next_hsp, to robisz to dobrze.

5

Wszystkie iteratory, jakie widziałem, wracają undef, aby zaznaczyć, że są wyczerpane. Dlatego powinieneś napisać: while (defined(my $hsp = $hit->next_hsp)). Poniższy przykład demonstruje błąd w pytaniu, które testy na prawdę (przerywa na 1) zamiast na zdefiniowanie (przechodzi "liftoff").

use 5.010; 
my $hit = __PACKAGE__; 

sub next_hsp { 
    state $i; 
    $i++; 
    return ['mumble', 4, 3, 2, 1, 0, 'liftoff']->[$i]; 
} 

# insert snippet from question here 
+0

To jest dobra uwaga. Sprawia, że ​​cała sprawa jest jeszcze bardziej nieporęczna, ale masz rację. – Mithaldu

+2

Typowy wzorzec dla iteratora to po prostu "return" bez żadnych argumentów na końcu. W kontekście skalarnym, który zamienia się w 'undef', ale jeśli powiesz' my ($ hsp) = $ hit-> next_hsp', to iterator może bezpiecznie zwrócić wartość undef (lub cokolwiek innego, co może być zinterpretowane jako false) w przypadkach gdzie ma to sens. Działa to, ponieważ lista zawierająca 1 wartość będzie miała wartość boolean true, niezależnie od tego, czy wartość jest równa false, czy nawet undef. –

+2

Wszystkie iteratory? Widziałem dość nieskończoną liczbę. :) –

3

nie martw się o grze w golfa, kod masz wygląda dobrze (inne niż pozostałe odpowiedzi dotyczące korzystania defined). Jeśli jednak powtarzasz ten schemat, 2 rzeczy przychodzą ci na myśl.

Pierwszy jest oczywisty, byłaby go do funkcji użytkowych, dzięki czemu masz my @list = expand($hit).

Drugie pytanie jest nieco głębiej - ale dla mnie pachnie bardziej niż gra w golfa. Cały punkt iteratorów polega na tym, aby je zużywać tak, jak ich potrzebujesz, więc jeśli często robisz to często, jesteś pewien, że naprawdę jest to właściwe? Być może przenoszenie tych danych poza własne API, więc jesteś ograniczony do innych wyborów, ale jeśli masz możliwość spożywania iteratora zamiast listy, może to będzie czystsze rozwiązanie.

Powiązane problemy