Schrift
[thread]10755[/thread]

Hashref deref



<< |< 1 2 >| >> 16 Einträge, 2 Seiten
Froschpopo
 2007-11-08 21:17
#102063 #102063
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
habe hier ein kleines Modul gebaut das Daten verwaltet:
Ein kleiner Auszug:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
sub new {
my $class = shift;
my $self = {};
bless($self, $class);
load(@_, $self) if @_;
return $self;
}

sub load {
my $self = shift;

if (@_) {
print "@_\n"; #Community::Storage=HASH(0x81717c8)
for (keys %{@_}) {
# wird leider nicht durchlaufen
$self->{$_} = $_[0]->{$_};
}
}
}

Das Problem ist nun, dass @_ zwar eine Hashreferenz enthält, diese aber scheinbar keinen Inhalt hat. Das stimmt aber nicht! @_ enthält sehrwohl eine Hashref die auch Inhalt enthält.

Daten bekommt das Modul, indem beim Objektaufbau eine Hashref übergeben wird:
my $obj = Community::Storage->new(\%params);
Froschpopo
 2007-11-08 21:39
#102065 #102065
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
hab jetzt ne Lösung gefunden die ich zwar nicht verstehe, die aber funzt:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sub new {
my $class = shift;
my $self = {};
bless($self, $class);
load($_[0], $self);
return $self;
}

sub load {
my ($args, $self) = shift;
if ($args) {
for (keys %{$args}) {
print "$_\n";
}
}
}

Versteh ich aber nicht, weil ob ich jetzt @_ oder $_[0] beziehe, ist doch dasselbe wenn shift das letzte Element eliminiert befindet sich doch nur noch ausschließlich die hashref in @_
pktm
 2007-11-08 21:46
#102073 #102073
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Wie sieht es denn aus, wenn du es dir mittels Data::Dumper anzeigen lässt?
http://www.intergastro-service.de (mein erstes CMS :) )
Froschpopo
 2007-11-08 22:25
#102076 #102076
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
Mit Data::Dumper kenne ich mich null aus. Hab ich auch noch nie eingesetzt.

Ich sag dir mal was das werden soll:
ich möchte das Modul nutzen, um Daten zu cachen und diese später wieder abzufragen.

Script
Code: (dl )
1
2
3
4
5
6
7
8
#!/usr/bin/perl

use strict;
use Community::Storage;

my $obj = Community::Storage->new({name => 'Hans Peter'});

print $obj->param('name'),"\n";


Das Modul dazu sieht bisher so aus:
Code: (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
package Community::Storage;

use strict;
our $VERSION = '1.0';

sub new {
my $class = shift;
my $self = {};
bless($self, $class);
load($_[0], $self) if @_;
return $self;
}

sub load { # hashref auslesen und speichern
my ($args, $self) = @_;
if ($args) {
for (keys %{$args}) {
$self->{$_} = $args->{$_};
}
}
}

sub param { # wert zurückliefern
my $self = shift;
return $self->{@_};
}

sub add { # neue Daten aufnehmen
my $self = shift;
my ($name, $value) = @_;
$self->{$name} = $value;
}

1;


Erklärung: load() soll die Daten cachen, die schon beim Objektaufbau übergeben werden. param() soll dann Daten abfragen können.

Leider habe ich aber noch das Problem, dass load() zwar die Daten in $self aufnimmt, aber diese kann ich komischerweise nicht in param() abfragen. Warum nicht?
Struppi
 2007-11-08 22:37
#102077 #102077
User since
2006-02-17
628 Artikel
BenutzerIn
[Homepage]
user image
Deine Ursprüngliche version enthält einen Fehler:
Code (perl): (dl )
load(@_, $self) if @_;


üblicherweise ist $self das erste Argument.

Code (perl): (dl )
1
2
sub load {
    my $self = shift;

und genau das erwartet deine Funktion auch.

Ohne Data::Dumper kann das Debuggen lästig werden und es ist auch einfach.
Code (perl): (dl )
1
2
sub load {
print Dumper \@_;

so hättest du gesehen was deine Funktion für Parameter bekommt.

Das was du da bastelst sieht für mich so aus, als ob du eher sowas wie http://search.cpan.org/~kasei/Class-Accessor-0.31/... suchst

Es gibt aber eine Reihe von Modulen die sowas ähnliches machen. Du erfindest gerade das Rad neu.
pktm
 2007-11-08 22:56
#102079 #102079
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
Class::Accessor sieht ja nett aus!
Kann man da eigentlich auch irgendwie einstellen, unter welchem Namen die Werte im Objekt gespeichert werden sollen?
Wenn man CGI::Application-Plugins und dergleichen entwickelt soll man z.B. darauf achten seinen eigenen Namensraum zu benutzen (z.B. $self->{MyPlugin::Key} oder soll die Variablen irgendwie so benennen, dass sie nicht mit anderen Dingen in Konflikt geraden (oder zumindest nicht so leicht (z.B. $self->{__MY_OWN_KEY}).
http://www.intergastro-service.de (mein erstes CMS :) )
pq
 2007-11-08 23:10
#102080 #102080
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
es muss $self->load(@_) heissen.
und meist nennt man sowas init()
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
Froschpopo
 2007-11-08 23:22
#102082 #102082
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
also dieser Accessor sieht ja gut und nett aus, aber ich möchte gern wissen wie man sowas selber macht sonst lern ich es ja nie.
habe jetzt folgendes:
Code: (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
package Community::Storage;

use strict;
use Data::Dumper qw/Dumper/;
our $VERSION = '1.0';

sub new {
my $class = shift;
my $self = {};
bless($self, $class);
$self->init($self, @_);
return $self;
}

sub init {
my $self = shift;

print Dumper \@_;
if (@_) {
for (keys %{@_}) {
$self->{$_} = $_[0]->{$_};
}
}
}

sub param {
my $self = shift;
return $self->{@_};
}

sub add {
my $self = shift;
my ($name, $value) = @_;
$self->{$name} = $value;
}

1;

Also laut Dumper befindet sich zum Zeitpunkt des Dumps Inhalt in @_.
Aber irgendwie bekomme ich das Hash nicht in $self hinein.
pktm
 2007-11-08 23:33
#102083 #102083
User since
2003-08-07
2921 Artikel
BenutzerIn
[Homepage]
user image
$self->init($self, @_); willst du so wohl nicht haben.
$self->init(); (ohne Parameter) übergibt der init()-Funktion $self als ersten Parameter.
Immer wenn du eine Methode (=Funktion einer Klasse) über ein Objekt aufrufst erhälst du das aufrufende Objekt als ersten Parameter.
mit my $self = shift; nimmst du dieses Objekt dann aus dieser Liste heraus.
Da shift; das Element aus der Argumentliste entfernt bleiben nur noch die Parameter übrig. Leider übergibst du $self zweimal. Einmal durch '$self->' und einmal als Bestandteil der Parameterliste '($self, @_)'.

Wirf daher mal das $self aus der Parameterliste raus und schau was passiert (und sieh es dir auch mit dem Dumper an):
Code: (dl )
1
2
3
4
5
# Aufruf: $self->init(@_).
sub init {
my $self = shift;
print Dumper \@_;
}
http://www.intergastro-service.de (mein erstes CMS :) )
Froschpopo
 2007-11-08 23:58
#102085 #102085
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
Verstehe! So langsam check ich diesen Dumper.
Jetzt funktioniert's sogar:
Code: (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
package Community::Storage;

use strict;
use Data::Dumper qw/Dumper/;
our $VERSION = '1.0';

sub new {
my $class = shift;
my $self = {};
bless($self, $class);
$self->init(@_);
return $self;
}

sub init {
my $self = shift;
if (@_) {
for (keys %{@_}) {
$self->{$_} = $_[0]->{$_};
}
}
}

sub param {
my $self = shift;
return $self->{$_[0]};
}

sub add {
my $self = shift;
my ($name, $value) = @_;
$self->{$name} = $value;
}

sub update {
my $self = shift;
$self->{$_[0]} = $_[1];
}

sub delete {
my $self = shift;
delete($self->{$_[0]});
}

1;


Irgendwelche Meinungen?
<< |< 1 2 >| >> 16 Einträge, 2 Seiten



View all threads created 2007-11-08 21:17.