Schrift
[thread]12838[/thread]

Verständnisfrage Datentypen (Array/Hash/literale "Listen")

Leser: 5


<< |< 1 2 3 >| >> 30 Einträge, 3 Seiten
tschloss
 2008-11-29 13:20
#116700 #116700
User since
2008-04-21
30 Artikel
BenutzerIn
[default_avatar]
Hi, durch mein Problem vor ein paar Tagen und eure Antworten hat sich mein Verständnis bzgl. der komplexen Datentypen jetzt geändert. Bevor ich mein Hirn aber nun endgültig "flushe", frage ich euch, ob mein Weltbild so korrekt ist:

1) Die Datentypen Array, Hash und literale Liste (zB "qw....") sind (intern) eigentlich immer Listen von Skalaren.
2) Je nach Datentyp/Kontext wird diese Liste nur anders interpretiert, vor allem was den Zugriff auf Elemente betrifft.
3) Zuweisungen auch zwischen verschiedenen Typen sind problemlos möglich (bei Hashes treten Elemente immer paarweise auf (interpretiert als key, value)). (Anmerkung: das könnte aber auch eine Intelligenz des Zuweisungsoperators sein, den Typ umzucasten)
4) Gleiches gilt auch für die Übergabe an Subroutinen. Es werden eigentlich immer nur Wertelisten übergeben. Wie die Routine diese dann interpretiert, ist deren Sache. Die Subroutine weiss nicht, dass die übergebenen Skalare ursprünglich mal ein Array oder Hash waren.

Ich habe etwas experimentiert und Perl hat obige Thesen eigentlich bestätigt.
Fragen aber:
1) Merkt Perl sich irgendwo einen Datentyp für Arrays/Hashes?
2) Woher weiss z.B. "Dumper", was sich hinter einer Referenz verbergen soll?
3) Benötigt Perl nicht irgendwelche Metainfos zum effizienteren Zugriff auf eine Struktur, und zwar unterschiedliche für ein Array/eine Liste bzw. einen Hash?

Danke für erhellende Kommentare. Das ist wichtig für meine weitere "Perl-Karriere ;)".

VG Thomas
renee
 2008-11-29 13:49
#116701 #116701
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Wenn Du wirklich wissen willst, wie die Datentypen intern aussehen, dann schau Dir mal http://search.cpan.org/src/GAAS/illguts-0.09/index... an.
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
lichtkind
 2008-11-29 14:28
#116702 #116702
User since
2004-03-22
5680 Artikel
ModeratorIn + EditorIn
[Homepage]
user image
im gegensatz zu perl 6 kennt perl 5 keine unterscheidung von liste und array. qw ist nur eine kompakte schreibweise einen array zu erzeugen.
Wiki:Tutorien in der Wiki, mein zeug:
kephra, baumhaus, garten, gezwitscher

Es beginnt immer mit einer Entscheidung.
tschloss
 2008-11-29 16:16
#116709 #116709
User since
2008-04-21
30 Artikel
BenutzerIn
[default_avatar]
Danke für die Komments. Für einen noch direkteren Bezug zu meinen Postulaten wäre ich noch dankbarer ;)
Aus renees Link gewann ich den oberflächlichen Eindruck, dass es zu einer Variablen sehr wohl noch einiges an Metainfo gibt. Das würde dann meine Zusatzfragen beantworten.

Demnach müßte ich meine Thesen leicht umformulieren:
1) Die Datentypen Array (inkl. "Liste") und Hash verhalten sich kompatibel zueinander. Alles läßt sich auf eine flache Liste zurückführen.
3) Zuweisungen auch zwischen verschiedenen Typen sind problemlos möglich (bei Hashes treten Elemente immer paarweise auf (interpretiert als key, value)). (Anmerkung: Das ist eine Intelligenz des Zuweisungsoperators)
4) Für die Übergabe an Subroutinen gilt: Es werden immer nur Wertelisten übergeben. Wie die Routine diese dann interpretiert, ist deren Sache. Die Subroutine weiss nicht, dass die übergebenen Skalare ursprünglich mal ein Array oder Hash (oder eben einzelne Paramter) waren.

Dass man gemäß (3) Hashes und Arrays mit qw einfach füllen kann, wußte ich. Dass man ohne Umweg eine Hash-Variable einer Array-Variablen und umgekehrt zuweisen kann, wußte ich nicht.
Vor allem (4) war mir nicht bewußt (wenn es denn so bestätigt wird): in einer Subroutine kommt immer nur eine Liste von Skalaren an, egal ob der Aufruf eine Liste von Werte oder einen Hash oder ein Array mitgegeben hat.

Liege ich richtig?
Danke
Thomas
renee
 2008-11-29 16:35
#116710 #116710
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
1) jein: Man kann zwar so etwas machen

Code (perl): (dl )
1
2
3
my @array = (1..10);
my %hash = @array;
@array = %hash;


Aber da Hashes keine bestimmte Reihenfolge hat, ist nicht garantiert (bzw. wird in den wenigsten Fällen so sein) dass das zweite @array die Elemente in der gleichen Reihenfolge hat wie das erste @array.

Hashes haben außerdem immer eine gerade Zahl an Einträgen (da immer Schlüssel und Wert). Also kann es passieren, dass durch das "hin- und herzuweisen" undef-Werte in das Array kommen. (einfach mal in obigem Beispiel die "10" durch eine "9" ersetzen.)

Weiteres Problem:
Code (perl): (dl )
1
2
3
my @array = (CGI->new, 1);
my %hash = @array;
@array = %hash;


Im Array ist das erste Element ein Objekt. Durch die Umwandlung in einen Hash wird jedes ungerade Element stringifiziert, da Schlüssel in einem Hash immer Strings sind. Also wirst Du beim zweiten @array so etwas als erstes Element haben: CGI=HASH(0x.....).
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
lichtkind
 2008-11-29 16:38
#116711 #116711
User since
2004-03-22
5680 Artikel
ModeratorIn + EditorIn
[Homepage]
user image
in Perl 5 sind Hashes (fast) nichts weiter als Arrays mit gerader länge und => ein weiteres lustiges komma. In Perl 6 wird das sehr anders.

Bedenke: Auch eine Referenz auf etwas (Array/hash/code) ist ein Skalar. Ja jede sub bekommt seine Parameter durch @_ was eine gewöhnliche arrayvariable ist und ja routinen können mit hilfe von wantarray den kontext in dem sie aufgerufen werden in erfahrung bringen und darauf reagieren.
Wiki:Tutorien in der Wiki, mein zeug:
kephra, baumhaus, garten, gezwitscher

Es beginnt immer mit einer Entscheidung.
tschloss
 2008-11-29 17:07
#116712 #116712
User since
2008-04-21
30 Artikel
BenutzerIn
[default_avatar]
Danke. Jetzt glaube ich klar zu sehen.
Happy WE
pq
 2008-11-29 17:30
#116713 #116713
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
liste ist kein datentyp.
eine variable kann nie eine liste sein. eine liste ist im prinzip nur der begriff für das,
was ein array enthält bzw. das, was während einer zuweisung herrenlos durch die luft liegt.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
betterworld
 2008-11-29 17:44
#116714 #116714
User since
2003-08-21
2613 Artikel
ModeratorIn

user image
Irgendwie kommen mir die Darstellungen hier etwas verdreht vor.

tschloss+2008-11-29 12:20:26--
Hi, durch mein Problem vor ein paar Tagen und eure Antworten hat sich mein Verständnis bzgl. der komplexen Datentypen jetzt geändert.

Werd ich mir gleich mal durchlesen, ich antworte trotzdem schonmal.
Quote
1) Die Datentypen Array, Hash und literale Liste (zB "qw....") sind (intern) eigentlich immer Listen von Skalaren.

Arrays und Hashes werden nicht genau gleich gespeichert. Hashes werden so gespeichert, dass man effizient auf bestimmte Schluessel zugreifen kann.

Wenn man Arrays oder Hashes initialisiert, geschieht dies in der Regel in beiden Fällen über eine Liste. Ebenso kann man ein Array oder einen Hash im Listenkontext benutzen, dann bekommt man wieder dieselben Werte, mit denen man es initialisiert hat.

Das ein Array aber zwischendurch anders gespeichert wird als ein Hash, merkt man schon daran, dass die obengenannte Liste beim Hash die Reihenfolge ändern kann.

Die erwähnte "Effizienz" beim Speichern eines Hashes geht natürlich verloren, wenn man die Werte wieder zu einer Liste verwandelt.

Code: (dl )
1
2
3
4
my @array = (1,2,3,4);
my %hash = (1,2,3,4);
print @array; # Benutze array im Listenkontext: Gibt dieselbe Liste, mit der ich es initialisiert habe
print %hash; # Gibt auch dieselbe Liste, aber die Reihenfolge kann anders sein: 3412

Quote
3) Zuweisungen auch zwischen verschiedenen Typen sind problemlos möglich (bei Hashes treten Elemente immer paarweise auf (interpretiert als key, value)). (Anmerkung: das könnte aber auch eine Intelligenz des Zuweisungsoperators sein, den Typ umzucasten)

Das passiert auch nur, weil die Daten von der Form, in der sie gespeichert sind, in eine flache Liste verwandelt werden und wieder zurück.
Code: (dl )
@array = %hash; # Hash wird zur Liste gemacht, damit wird dann das Array initialisiert

Quote
1) Merkt Perl sich irgendwo einen Datentyp für Arrays/Hashes?

Ja, da (wie oben erwähnt) ein Hash ganz anders gespeichert wird als ein Array, wird auch ein Flag mitgespeichert, was es ist. Bei Variablen (%hash vs @array) merkt man ja eh schon am Sigil (bzw Symboltabellen-Slot-Dings), welcher Variablentyp es ist, aber bei Referenzen merkt man, dass perl auch sonst weiß, was was ist:
Code: (dl )
1
2
3
4
my $ref = []; # array-referenz
print $ref; # ARRAY(...)
$ref = {}; # Hash-Referenz
print $ref; # HASH(...)


Quote
3) Benötigt Perl nicht irgendwelche Metainfos zum effizienteren Zugriff auf eine Struktur, und zwar unterschiedliche für ein Array/eine Liste bzw. einen Hash?

Eben darum wird ein Hash komplett anders gespeichert als ein Array.

lichtkind+2008-11-29 13:28:44--
im gegensatz zu perl 6 kennt perl 5 keine unterscheidung von liste und array. qw ist nur eine kompakte schreibweise einen array zu erzeugen.

In Perl 5 gibt es auch einen Unterschied zwischen Array und Liste. Ein Array bezeichnet eine bekannte "Speicherstelle", also eine Variable oder eine Referenz. Liste ist zum einen ein Kontext, zum anderen tritt es überall auf, wo mehrere Werte umhergeschoben werden. Was eine Subroutine zurückgibt, ist zum Beispiel eine Liste.
(Edit: Ich wollte mit diesem Absatz genau das sagen, was auch pq geschrieben hat, während ich getippt habe.)

Den Unterschied merkt man immer wieder auf subtile Weise:
Code: (dl )
1
2
3
4
5
6
7
8
9
sub foo {
return "alpha", "beta";
}
my @array = ("alpha", "beta"); # Array wird mit Liste initialisiert

my $scalar = foo(); # Liste im skalaren Kontext: Ergibt das letzte Element
print $scalar; # "beta"
$scalar = @array; # Array im skalaren Kontext: Ergibt die Anzahl
print $scalar; # 2
LanX-
 2008-11-29 18:16
#116715 #116715
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
noch so etwas was man nicht gleich beigebracht bekommt...weil es auch wenige genau wissen:

IMHO:
3 Datentypen Scalar, Hash, Array
2 Kontexte: Scalar und Liste ...(mind. bei Kontexten ist auch von Subtypen wie Boolean usw die Rede...)

http://perldoc.perl.org/perlfaq4.html#What-is-the-difference-between-a-list-and-an-array%3f

Man könnte vereinfachend sagen: Listen sind ein Zwischenformat aber nicht ein Typ (einer Variablen).
<< |< 1 2 3 >| >> 30 Einträge, 3 Seiten



View all threads created 2008-11-29 13:20.