Jak mogę wydrukować zawartość skrótu w Perlu?

167

Nadal drukuję mój hash jako # segmentów / # przydzielonych. Jak wydrukować zawartość mojego skrótu?

whileNajlepiej byłoby bez pętli (na przykład jednowarstwowy byłby najlepszy).

Kys
źródło

Odpowiedzi:

253

Data :: Dumper to twój przyjaciel.

use Data::Dumper;
my %hash = ('abc' => 123, 'def' => [4,5,6]);
print Dumper(\%hash);

wyjdzie

$VAR1 = {
          'def' => [
                     4,
                     5,
                     6
                   ],
          'abc' => 123
        };
tetromino
źródło
3
oryginalny plakat może również chcieć przyjrzeć się różnym opcjom Data :: Dumper, w szczególności włączenie „Sortkeys” może być bardzo przydatne
plus plus
1
@JonathanDay Brakowało mi tego szczegółu i było to pomocne! Dzięki!
Sos
5
Co to znaczy dodać ukośnik przed%?
szampon
16
Operator @shampoo slash tworzy referencję, trochę jak &operator w C i C ++. Powodem, dla którego ma to znaczenie w tym kontekście jest to, że w Perlu, jeśli wywołasz funkcję z wartością skrótu jako argumentem, ta wartość skrótu zostanie wyświetlona i rozszerzona na wiele argumentów - więc %hsh=("a" => 1, "b" => 2); foo(%hsh);będzie to równoważne foo("a", 1, "b", 2). Jeśli zamiast tego chcesz, aby funkcja działała na samym skrócie , musisz przekazać odniesienie do skrótu: foo(\%hsh);Zobacz perldoc.perl.org/perlsub.html#Pass-by-Reference
tetromino
63

Łatwo:

print "$_ $h{$_}\n" for (keys %h);

Eleganckie, ale w rzeczywistości o 30% wolniejsze (!):

while (my ($k,$v)=each %h){print "$k $v\n"}
Jonathan Graehl
źródło
9
Sleazy: print "@_ \ n" while @_ = each% h
FMc
Myślę, że masz na myśli print "$_ $h{$_}\n" for (keys %h);, $kże nie istnieje w tym przykładzie.
Chas. Owens
4
Przed złożeniem oświadczeń dotyczących wydajności należy również przeprowadzić analizę porównawczą (lub przynajmniej określić typ wydajności, o którym mówisz). forPętla jest większa niż whiledo co najmniej 10000 klawiszy: gist.github.com/151792
Chas. Owens
1
Oczywiście masz rację re: $ k. Ale jest bardziej wydajne w Perlu 6! :) Tak, też masz rację. Nigdy nie pomyślałbym o optymalizacji lub profilowaniu mojego Perla, ale cieszę się, że się tego dowiedziałem. Oczywiście każdy powinien być bardziej wydajny (ponieważ nie ma dodatkowego wyszukiwania skrótu na kluczu). Ale to ~ 30% wolniej!
Jonathan Graehl
Cześć, Jonathan Graehl. Przepraszam, wciąż nie rozumiem. Mówisz, że każdy jest ~ 30% wolniejszy, na podstawie czego? Czy za każdym razem, w każdej sytuacji, różnica wynosi 30%?
Carlos Sá
24

Do celów debugowania będę często używać YAML.

use strict;
use warnings;

use YAML;

my %variable = ('abc' => 123, 'def' => [4,5,6]);

print "# %variable\n", Dump \%variable;

Prowadzi do:

# %variable
---
abc: 123
def:
  - 4
  - 5
  - 6

Innym razem użyję Data::Dump. Nie musisz ustawiać tylu zmiennych, aby wyświetlić je w ładnym formacie niż w przypadku Data::Dumper.

use Data::Dump = 'dump';

print dump(\%variable), "\n";
{ abc => 123, def => [4, 5, 6] }

Niedawno Data::Printerużywałem do debugowania.

use Data::Printer;
p %variable;
{
    abc   123,
    def   [
        [0] 4,
        [1] 5,
        [2] 6
    ]
}

(Wynik może być znacznie bardziej kolorowy na terminalu)

W przeciwieństwie do innych przykładów, które tutaj pokazałem, ten jest przeznaczony wyłącznie do wyświetlania. Co pojawia się łatwiej, jeśli wyrzucisz strukturę zmiennej powiązanej lub obiektu.

use strict;
use warnings;

use MTie::Hash;
use Data::Printer;

my $h = tie my %h, "Tie::StdHash";
@h{'a'..'d'}='A'..'D';
p %h;
print "\n";
p $h;
{
    a   "A",
    b   "B",
    c   "C",
    d   "D"
} (tied to Tie::StdHash)

Tie::StdHash  {
    public methods (9) : CLEAR, DELETE, EXISTS, FETCH, FIRSTKEY, NEXTKEY, SCALAR, STORE, TIEHASH
    private methods (0)
    internals: {
        a   "A",
        b   "B",
        c   "C",
        d   "D"
    }
}
Brad Gilbert
źródło
posiadanie kolorów jest "fajne", ale albo robię coś źle, albo używam "use Data :: Printer; p% var;" nie drukuje strzałek w skrótach, a dla nowicjusza takiego jak ja to pomaga
Sos
@Sosi Jeśli spojrzysz na wynik w odpowiedzi, zobaczysz, że nie wyświetla się =>tak, jak oczekujesz. Zamiast tego zawsze wypisuje klucz, kilka spacji, a następnie wartość. Co pomaga człowiekowi skanować dane wyjściowe.
Brad Gilbert
12

Odpowiedź zależy od tego, co jest w twoim hashu. Jeśli masz prosty skrót, plik simple

print map { "$_ $h{$_}\n" } keys %h;

lub

print "$_ $h{$_}\n" for keys %h;

wystarczy, ale jeśli masz hash, który jest wypełniony referencjami, znajdziesz coś, co może przejrzeć te odwołania i wygenerować rozsądny wynik. To chodzenie po odniesieniach jest zwykle nazywane serializacją. Istnieje wiele modułów, które implementują różne style, niektóre z bardziej popularnych to:

Ze względu na to, że Data::Dumperjest częścią podstawowej biblioteki Perla, jest prawdopodobnie najpopularniejszą; jednak niektóre inne moduły oferują bardzo dobre rzeczy.

Chas. Owens
źródło
10

Mój ulubiony: Smart :: Komentarze

use Smart::Comments;
# ...

### %hash

Otóż ​​to.

Axeman
źródło
5
Przepraszamy, głosuj w dół ode mnie na rzeczy, które przechwytują komentarze pod kątem rzeczywistej funkcjonalności. Programista zajmujący się konserwacją mógłby spędzić cały dzień na próbach wyjaśnienia, dlaczego taki kod drukuje nieoczekiwane rzeczy.
MikeKulls
2
@MikeKulls, np. To filtr źródłowy, więc rozumiem. Poza tym, mając napisane skrypty, które sprawdzają każdy moduł, który wprowadziłem do produkcji, czy tak nie jest use Smart::Comments, widzę to również z tej perspektywy. Ale licznik Smart::Commentszachowuje się całkiem dobrze jako moduł o określonym zakresie , nie powinno być zachowania wyjścia w żadnym module, który również nie używa SC. Tak więc problem byłby izolowany do tych zakresów za pomocą instrukcji użycia . Jeśli mówisz, że programista konserwacyjny nie ma obowiązku czytać dokumentacji dotyczącej dołączonych modułów, nie mogę się z tym zgodzić. Mimo to dziękuję za komentarz
Axeman,
7
Nie mówię, że nie ponoszą odpowiedzialności, ale prawdopodobnie nie będzie to pierwsza rzecz, której szukają. Nigdy wcześniej nie widziałem modułu inteligentnych komentarzy, nie wiedziałbym, dlaczego powyższy kod coś drukuje. Mógłbym spędzić dni pomijając komentarz, a nawet go nie przetwarzać, ponieważ komentarze nie powinny nic robić. Zmuszanie ich do zrobienia czegoś jest bardzo złe. Mogą być używane do generowania dokumentacji itp., O ile nie zmieniają zachowania programu.
MikeKulls
4

Pętla:

foreach(keys %my_hash) { print "$_ / $my_hash{$_}\n"; }

Funkcjonalny

map {print "$_ / $my_hash{$_}\n"; } keys %my_hash;

Ale ze względu na czystą elegancję musiałbym wybrać wrang-wrang. Jako własny kod wybrałbym moje foreach. Lub użycie Dumpera Tetro.

Paul Nathan
źródło
3
Nie ma funkcjonalnej różnicy między Twoimi zastosowaniami foreachi map. mappowinny być wykorzystywane do listy przemian, a nie w kontekście void aby emulować dla pętli
friedo
byłoby interesujące zobaczyć wyniki „kodu bajtowego” każdego z nich ... Zastanawiam się, czy mapa jest mniej lub bardziej wydajna.
Ape-inago
2

Z moich doświadczeń wynika, że ​​najłatwiej jest po prostu użyć Dumpvalue .

use Dumpvalue;
...
my %hash = { key => "value", foo => "bar" };
my $dumper = new DumpValue();
$dumper->dumpValue(\%hash);

Działa jak urok i nie musisz się martwić o formatowanie skrótu, ponieważ wyświetla go tak, jak robi to debugger Perla (świetne do debugowania). Ponadto Dumpvalue jest dołączony do podstawowego zestawu modułów Perla, więc nie musisz zadzierać z CPAN, jeśli stoisz za jakimś drakońskim proxy (tak jak ja w pracy).

Weegee
źródło
1

Jeśli chcesz być pedantyczny i trzymać go w jednej linii (bez instrukcji użycia i huku), to trochę wycofam się z odpowiedzi tetromino i zasugeruję:

print Dumper( { 'abc' => 123, 'def' => [4,5,6] } );

Nie robię nic specjalnego poza używaniem anonimowego hasha do pominięcia zmiennej tymczasowej;)

Kyle Walsh
źródło
OP mówi, że ma „mój hash”, który wymaga wydrukowania. Ta odpowiedź jest po prostu sprytem sama w sobie
justintime
OP miał nadzieję zrobić to w jednej linii. Po prostu pokazywałem jednowierszowy sposób na zrobienie tego. Więc to jest warte głosowania negatywnego?
Kyle Walsh
1

Dodaję jedno miejsce na każdy element hasha, aby dobrze go zobaczyć:

print map {$_ . " "} %h, "\n";
carlos_lm
źródło
1

Bardzo lubię sortować klucze w jednym kodzie liniowym:

print "$_ => $my_hash{$_}\n" for (sort keys %my_hash);
labista
źródło