Thread Konstruktorverständnis
(18 answers)
Opened by leo11 at 2009-06-27 21:01
Mir ging es eigentlich nur um das Prinzip: Nur weil die Magie beim Zugriff nicht mehr gewünscht ist, muss die Datenstruktur nicht in jedem Falle unbrauchbar sein.
Die Magie der Pseudohashes kann man allerdings auch auf anderem Wege wieder nachbauen -- zum Beispiel mit folgender Klasse: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 package PseudoHash; use strict; use warnings; use List::Util qw/max/; # Constructor # Params: # $self = Existing object reference or package # @fields = Field names to be created in the new pseudo hash # Returns: # A new blessed object sub new { my ($self, @fields) = @_; my ($class, $layout) = do { if (my $class = ref $self) { ($class, $self->[0]); } else { ($self, {}); } }; if (@fields > 0) { $layout = { %$layout }; my $offset = max(0, values %$layout) + 1; foreach my $field (@fields) { $layout->{$field} = $offset++; } } bless [ $layout ], $class; } # Accesses a field of the pseudo hash by name # Params: # $self = Reference to the pseudo hash # $field = Name of the field # Returns: # An lvalue representing the field sub field : lvalue { my ($self, $field) = @_; my $offset = $self->[0]->{$field}; die "No such field '$field' in $self" unless (defined $offset); $self->[$offset]; } Dazu noch ein Anwendungsbeispiel: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 use Data::Dumper; local ($,, $\) = (' ', "\n"); # Create a pseudo hash my $ph = new PseudoHash(qw/FOO BAR BAZ/); # Assign and read existing fields $ph->field('FOO') = 42; print 'FOO:', $ph->field('FOO'); $ph->field('BAR') = 23; print 'BAR:', $ph->field('BAR'); # Create a pseudo hash with identical structure as $ph my $pi = $ph->new(); # Assign and read an existing field $pi->field('BAR') = 23; print 'BAR:', $pi->field('BAR'); # Create a pseudo hash with structure based on $ph my $pj = $ph->new(qw/QUARK/); # Assign and read an existing field $pj->field('QUARK') = 'Hallo'; print 'QUARK:', $pj->field('QUARK'); # Show the structure of the pseudo hashes print Dumper [ $ph, $pi, $pj ]; # Try to access a non-existing field $ph->field('BOING'); # generates an error Wie gewünscht gibt's hier einen harten Fehler, wenn man auf nicht existierende Felder zugreift. Und natürlich kann man das oben definierte Paket PseudoHash als Basisklasse für anderen Code verwenden. When C++ is your hammer, every problem looks like your thumb.
|