Programming Perl
Posts 1-5 of 5
-
Mario Bono Premium MemberThe company name is only visible to registered members.call_user_func
Hallo in die Runde.
Ich habe eine Frage siehe Betreff. In PHP ist es ja möglich z.b. in einer inc Klassen zu definieren die unter anderem auch user callback Funktionen die aber in der Aufrufenden php Datei definiert sind aufzurufen.
Ich würde sowas gerne in Perl nachbauen. Ja ich weiß ich kann meine user functions gleich in der pm einbauen oder von einer anderen importieren usw. aber das ist nicht das was ich suche, sondern eben wie in PHP möglich. Irgendeine PM in der ich meine Classen / Funktionen usw definiere. Eine Pl welche diese PM used oder required, dort sollen Funktionen definiert werden, welche aus der PM ausgerufen werden.
Ahja, bitte keine Warum und Unnötig oder sonstigen Kommentare, einfach nur geht so, geht nicht, nicht möglich, aus ;-)
Herzlichen Dank schon mal im Vorraus.
- 17 Sep 2010, 08:05 am
-
Bernhard Schmalhofer Premium MemberThe company name is only visible to registered members.Re: call_user_func
Hallo,
ich bin mir nicht sicher ob ich die Frage verstanden habe, was ist mit PM und PI gemeint.
Die Antwort lautet natürlich, wie fast immer in Perl, ja es geht.
Hier ein Primitivbeispiel mit den zwei Dateien MeinFramework.pm und MeineApp.pl.
Die Sub in in MeinFramework,pm ruft eine Sub die in MeineApp.pl definiert ist auf.
MeinFramework.pm:
----------------------------
use strict;
use warnings;
package MeinFramework;
sub rufe_callback_auf
{
print "Callback aus dem aufrufenden script soll aufgerufen werden.\n";
mein_callback();
}
1;
MeineApp.pl:
----------------:
use strict;
use warnings;
use MeinFramework;
MeinFramework::rufe_callback_auf();
package MeinFramework;
sub mein_callback {
print "Sub mein_callback() in MeineApp.pl\n";
}
Wenn es um Callback-Funktionen geht würde ich aber die Namen der Funktion nicht fest verdrahten, Es ist eigentlich immer besser, die callback-Funktion als Funktionsargument zu übergeben.
Für größere Anwendungen kann man sich natürlich auch ein Plugin-system überlegen, oder noch besser eines auf CPAN suchen.
Viele Grüße,
Bernhard Schmalhofer
- 17 Sep 2010, 10:05 am
-
Mario Bono Premium MemberThe company name is only visible to registered members.Re^2: call_user_func
Hallo Herr Schmalhofer
Sie haber mir sehr geholfen, manchmal sieht man den Wald vor lauter Bäumen nicht ;-)
So sieht dann mein TestConstruct bzw Perl Version der call_user_func für PHP aus:
PM - meine damit Module;
package Testen;
use strict;
use warnings;
sub new()
{
my ($class) = shift;
my $self = { };
$self->{user_function} = undef;
bless ($self, $class);
return ($self);
}
sub call_user_function
{
my ($self) = @_;
my $functionname = $self->{user_function};
my $functionnameasref = \&$functionname;
&$functionnameasref("Called from PM $functionname.\n");
}
sub do_something
{
my ($self) = @_;
if (defined($self->{user_function})) { $self->call_user_function(); }
else { print "no user function - do something else\n" };
}
1;
PL - test.pl
use strict;
use warnings;
require "Testen.pm";
package Testen;
my $share = new Testen();
sub newfunction($) # my user function
{
my $text = shift;
die if !defined($text);
print "newfunction from PL -> $text\n";
}
$share->do_something; # do nothing - no function set
$share->{user_function} = "newfunction"; # set name of function
$share->do_something; # do something
# bla bla bla
# do something
exit;
OUTPUT, so wie erwartet - test.pl:
no user function - do something else
newfunction from PL -> Called from PM newfunction.
Also nochmals herzlichen Dank für die schnelle und vor allem kompetente Antwort.
Grüße
Mario Bono
- 17 Sep 2010, 11:14 am
-
Bernhard Schmalhofer Premium MemberThe company name is only visible to registered members.Re^3: call_user_func
Weil es so schön war kommt hier noch ein Version in den die Anwenderfunktion als Referenzen auf Subroutinen
übergeben werden. Dann muss man auch nicht auf die Packagenamen aufpassen.
Der nächste Schritt wäre übrigens die Verwendung von Closures. Closures gibt es in Perl schon immer, in PHP ab Version 5.3.
Für Perlfragen gibt es übrigens auch die sehr empfehlenswerte Perl-Community,
http://www.perl-community.de/.
Testen.pm:
---------------
package Testen;
use strict;
use warnings;
sub new
{
my ($class) = shift;
my $self = {
user_function => undef,
};
bless $self, $class;
return $self;
}
sub set_user_function
{
my $self = shift;
my ( $user_function ) = @_;
$self->{user_function} = $user_function;
return;
}
sub do_something
{
my $self = shift;
if ( defined $self->{user_function} ) {
my $package = caller();
# call $self->{user_function} with a string
$self->{user_function}->( "Called from package $package" );
}
else {
print "no user function - do something else\n";
}
}
1;
test.pl:
--------
use strict;
use warnings;
use Testen;
package MyTestScript;
my $share = Testen->new();
# named user function
sub newfunction
{
my $text = shift;
die if ! defined $text;
print "newfunction from PL -> $text\n";
}
# anonymous user function
my $newerfunction = sub
{
my $text = shift;
die if ! defined $text;
print "newerfunction from PL -> $text\n";
};
$share->do_something(); # do nothing - no function set
$share->set_user_function( \&newfunction );
$share->do_something(); # do something
- 18 Sep 2010, 1:03 pm
-
- 19 Sep 2010, 07:10 am
