Thread Subroutine aus Variable (4 answers)
Opened by rc27 at 2013-06-26 09:39

topeg
 2013-06-26 10:58
#168594 #168594
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Im allgemeinen ist es eine schlechte Idee Stings als Funktionsnamen zu benutzen. Die Fähigkeit von Perl stammt noch aus Zeiten als es dafür keine Alternativen gab. Das Problem ist nämlich das du keine Kontrolle darüber hast welche Funktionen benutzt werden dürfen. so kann aus jedem importieren Modul jede Funktion benutzt werden. Damit lässt sich einigen schaden

Besser ist es du benutzt einen Hash mit Funktionsreferenzen oder anonymen Funktionen um das zu lösen. Etwa so:
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
#!/usr/bin/perl
use strict;
use warnings;

my %funktions=(
  default => \&do_default,
  sub1    => \&do_sub1,
  sub2    => \&do_sub2,
  sub3    => \&do_sub3,
);

open(my $fh, '<', $file) or die( "ERROR OPEN $file ($!)\n" );
while(my $cmd=<$fh>)
{
  chomp($cmd);
  # Kommenatre entfernen
  next if($cmd=~/^\s*#/);

  # Error wenn eine Unbekannter Aufruf kommt:
  die("CMD:$cmd FILE:$file LINE:$. Not implemented!") unless exists $funktions{$cmd};

  $funktions{$cmd}->();
}
close($fh);

##############################
sub do_default { print "DOING DEFAULT\n" }
sub do_sub1 { print "DOING SUB1\n" }
sub do_sub2 { print "DOING SUB2\n" }
sub do_sub3 { print "DOING SUB3\n" }


Wenn es dir aber egal ist welche Funktionen aufgerufen werden können kannst du es so machen:
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
#!/usr/bin/perl
use strict;
use warnings;

open(my $fh, '<', $file) or die( "ERROR OPEN $file ($!)\n" );
while(my $cmd=<$fh>)
{
  chomp($cmd);
  # Kommenatre entfernen
  next if($cmd=~/^\s*#/);

  my $fref=main->can($cmd);

  # Error wenn eine Unbekannter Aufruf kommt:
  die("CMD:$cmd FILE:$file LINE:$. Not implemented!") unless $fref;

  $fref->();
}
close($fh);

##############################
sub do_default { print "DOING DEFAULT\n" }
sub do_sub1 { print "DOING SUB1\n" }
sub do_sub2 { print "DOING SUB2\n" }
sub do_sub3 { print "DOING SUB3\n" }


can testet ob eine Funktion im angebenden Namespace existiert. Hier wird halt getestet ob ein Passender Funktionsname in "main", dem default Namespace von Perl, existiert. Zurück gegeben wird eine refenzen auf die angefragte Funktion oder undef.

Willst du auf jede Mögliche Funktion in allen Namespaces zugreifen können musst du das Perl mitteilen:
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
#!/usr/bin/perl
use strict;
use warnings;

open(my $fh, '<', $file) or die( "ERROR OPEN $file ($!)\n" );
while(my $cmd=<$fh>)
{
  chomp($cmd);
  # Kommenatre entfernen
  next if($cmd=~/^\s*#/);

  {
    no strict 'refs';
    &$cmd();
  }
}
close($fh);

##############################
sub do_default { print "DOING DEFAULT\n" }
sub do_sub1 { print "DOING SUB1\n" }
sub do_sub2 { print "DOING SUB2\n" }
sub do_sub3 { print "DOING SUB3\n" }

View full thread Subroutine aus Variable