Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]11069[/thread]

Hashref bei anonymer Funktion



<< |< 1 2 3 >| >> 26 Einträge, 3 Seiten
Froschpopo
 2007-12-28 05:40
#104161 #104161
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
Habe folgendes Beispiel:
Code (perl): (dl )
1
2
3
4
5
6
my $hashref = sub {
    my %list = (1 => 'test');
    return \%list;
};

print $hashref->{1},"\n";

warum klappt das nicht?

Er erzählt mir immer etwas von wegen "Not a HASH reference".
Wenn ich mir dann mal $hashref ohne Parameter ausgeben lasse, dann krieg ich auch immer nur ne CODE(X)-Funktionsreferenz zurück anstatt der gewünschten Hashref.
Struppi
 2007-12-28 08:16
#104162 #104162
User since
2006-02-17
628 Artikel
BenutzerIn
[Homepage]
user image
Du hast eigentlich dir schon die Antwort selber gegeben. $hashref ist eine Funktionsreferenz, keine Hashreferenz. Anwelcher Stelle wird denn die Funktion aufgerufen?
Froschpopo
 2007-12-28 09:15
#104163 #104163
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
Die Funktion wird in einer anderen Funktion aufgerufen, in etwa so:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
sub ablauf {
   my $users = sub {
      #%liste erarbeiten
      return \%liste;
   };

   my $fotos = sub {
      #%liste erarbeiten
      return \%liste;
   };
}


Ich mache dies, damit ich einfache Variablen-Namen wie $sth, @bind usw. mehrfach innerhalb einer Funktion nutzen kann.
Ich hatte früher benannte Funktionen hierfür, aber das ist mir mittlerweile trotz zahlreiche Objekte zu unübersichtlich.
Ich bin zudem kein Freund von langen Variablen-Namen und bleibe lieber bei $sth, @bind, $id usw.

Übrigens: Die anonymen Funktionen sind meistens relativ klein. In der Regel wird nur ein kleines SQL-Statement ausgeführt.
Ich hab blos keine Lust mir jedesmal neue Namen für irgendwelche Handles usw einfallen zu lassen, deshalb möchte ich sie lieber verschachten (s.o.).
renee
 2007-12-28 09:43
#104164 #104164
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Code (perl): (dl )
1
2
3
4
5
6
my $hashref = sub {
    my %list = (1 => 'test');
    return \%list;
}->();

print $hashref->{1},"\n";


Man beachte das ->(). Ohne das ->() erzeugst Du eine Subroutinenreferenz und weist diese dann $hashref zu. Mit dem ->() wird erst die Subroutinenreferenz erzeugt, durch das ->() ausgeführt und das Ergebnis der Subroutine an $hashref zugewiesen...
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/
Linuxer
 2007-12-28 09:52
#104165 #104165
User since
2006-01-27
3890 Artikel
HausmeisterIn

user image
Hi,

warum nicht so?

Code (perl): (dl )
1
2
3
my $ref = do { my %list = ( 1 => 'test' ); \%list; };
print $ref, $/;
print $ref->{1}, $/;


[edit]code reviewed[/eidt]
meine Beiträge: I.d.R. alle Angaben ohne Gewähr und auf Linux abgestimmt!
Die Sprache heisst Perl, nicht PERL. - Bitte Crossposts als solche kenntlich machen!
Froschpopo
 2007-12-28 10:44
#104170 #104170
User since
2003-08-15
2653 Artikel
BenutzerIn
[default_avatar]
ich finde das zu komplziert und arbeite auch nicht so gerne mit do. $/ bin ich auch nicht gewohnt.

Ich hab aber mal noch eine andere Frage:
auf das vorherige Bsp:
Code (perl): (dl )
1
2
3
4
5
my $hashref = sub {
    return shift;
};
print $hashref->(5),"\n";
print $hashref->(125),"\n";

Wo ist eigentlich der Unterschied zu:
Code (perl): (dl )
1
2
3
4
5
my $hashref = sub {
    return int(rand(1000));
};
print $hashref->(),"\n";
print $hashref->(),"\n";  #ergibt dasselbe ergebnis wie beim ersten print()


Wie oft wird $hashref denn nun ausgeführt? Nur einmal zum Zeitpunkt der Deklarierung? Oder jedesmal, wenn ich irgendwo $hashref auftaucht?

Konkret:
Code (perl): (dl )
1
2
3
4
5
my $hashref = sub {
    return $dbh->selectrow_array("SELECT * FROM users");
};
print $hashref->(),"\n";
print $hashref->(),"\n";

Ist diese Funktion jetzt statisch oder nicht? Das wäre ja blödsinn, wenn bei jedem print die ganze Datenbankabfrage neu ausgeführt wird.
Struppi
 2007-12-28 10:49
#104172 #104172
User since
2006-02-17
628 Artikel
BenutzerIn
[Homepage]
user image
Froschpopo+2007-12-28 08:15:48--
Die Funktion wird in einer anderen Funktion aufgerufen, in etwa so:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
sub ablauf {
   my $users = sub {
      #%liste erarbeiten
      return \%liste;
   };

   my $fotos = sub {
      #%liste erarbeiten
      return \%liste;
   };
}
Wie kommst du darauf, dass hier ein Funktion aufgerufen wird? Du weist den Variabeln eine sub-Referenz zu, mehr nicht.

Wobei das für mich, so wie du es beschreibst, keinen Sinn macht. Diese Variante dient ja nicht der Übersichtlichkeit, sondern um Funktionen zur Laufzeit zu erzeugen, die an anderer Stelle aufgerufen werden, damit kannst du verschiedene Verhaltensweisen mit dem gleichen Objekt oder Funktion erzeugen.
Linuxer
 2007-12-28 10:52
#104173 #104173
User since
2006-01-27
3890 Artikel
HausmeisterIn

user image
Hi,

ich finde "do {}" weniger kompliziert als "sub {}->()";

$/ ist jedem freigestelt zu nutzen oder nicht. Steckt ja nur im Anschauungscode.

$hashref wird gar nicht ausgeführt, da es nur eine Code-Referenz ist.

Der referenzierte Code wird jedesmal ausgeführt, wenn $hashref entsprechend dereferenziert wird.

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
$  perl
my $ref = sub { return int( rand( 1000 ) ); };


for ( 1 .. 5 ) {
print $ref->(), $/;
}

211
346
330
996
789
meine Beiträge: I.d.R. alle Angaben ohne Gewähr und auf Linux abgestimmt!
Die Sprache heisst Perl, nicht PERL. - Bitte Crossposts als solche kenntlich machen!
Struppi
 2007-12-28 10:53
#104175 #104175
User since
2006-02-17
628 Artikel
BenutzerIn
[Homepage]
user image
Froschpopo+2007-12-28 09:44:47--
Code (perl): (dl )
1
2
3
4
5
my $hashref = sub {
    return shift;
};
print $hashref->(5),"\n";
print $hashref->(125),"\n";

Wo ist eigentlich der Unterschied zu:
Code (perl): (dl )
1
2
3
4
5
my $hashref = sub {
    return int(rand(1000));
};
print $hashref->(),"\n";
print $hashref->(),"\n";  #ergibt dasselbe ergebnis wie beim ersten print()


Wie oft wird $hashref denn nun ausgeführt? Nur einmal zum Zeitpunkt der Deklarierung? Oder jedesmal, wenn ich irgendwo $hashref auftaucht?
Du weist dem Skalar eine Funktion zu ausgeführt wird sie erst mit dem Aufruf ->(). Im zweitem Beispiel mit einem festen Rückgabewert. Im ersten wird der Parameter den du übergibst zurückgegeben.

Froschpopo+2007-12-28 09:44:47--
Konkret:
Code (perl): (dl )
1
2
3
4
5
my $hashref = sub {
    return $dbh->selectrow_array("SELECT * FROM users");
};
print $hashref->(),"\n";
print $hashref->(),"\n";

Ist diese Funktion jetzt statisch oder nicht? Das wäre ja blödsinn, wenn bei jedem print die ganze Datenbankabfrage neu ausgeführt wird.
Natürlich wird diese bei dem Aufruf neu ausgeführt. Ich habe wirklich den Eindruck, dass du was ganz anderes willst
renee
 2007-12-28 10:55
#104176 #104176
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Froschpopo+2007-12-28 09:44:47--
Wo ist eigentlich der Unterschied zu:
Code (perl): (dl )
1
2
3
4
5
my $hashref = sub {
    return int(rand(1000));
};
print $hashref->(),"\n";
print $hashref->(),"\n";  #ergibt dasselbe ergebnis wie beim ersten print()


Wie oft wird $hashref denn nun ausgeführt?


Zweimal

Quote
Nur einmal zum Zeitpunkt der Deklarierung?


nein

Quote
Oder jedesmal, wenn ich irgendwo $hashref auftaucht?


Immer dann wenn Du $hashref->() machst... Und nur dann wenn Du mit ->() perl sagst, dass die Subreferenz dereferenziert und ausgeführt werden soll!
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/
<< |< 1 2 3 >| >> 26 Einträge, 3 Seiten



View all threads created 2007-12-28 05:40.