Schrift
[thread]5630[/thread]

Code, der Code erzeugt und verwendet: geht das? (Seite 2)



<< |< 1 2 >| >> 16 Einträge, 2 Seiten
Crian
 2003-08-18 16:34
#61753 #61753
User since
2003-08-04
5866 Artikel
ModeratorIn
[Homepage]
user image
Hier mal ein funktionierendes Beispiel:

AB.pl
Code (perl): (dl )
1
2
3
4
5
6
7
8
#!/usr/bin/perl
use diagnostics;
use strict;
use warnings;

use A;

A::mach();


A.pm:
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
package A;

use diagnostics;
use strict;
use warnings;

use FindBin;
use lib &#36FindBin::Bin;

sub mach {
    machdies();
    machdas();
}

sub _erzeuge_modul {
   open(F, ">&#36FindBin::Bin/B.pm")
       or die "Unable to create B.pm:&#36!";
   print F "sub machdies { print \"machdies\\n\" }\n";
   print F "sub machdas  { print \"machdas\\n\"  }\n";
   print F "1;\n";
   close(F) or die "Unable to close Modul.pm:&#36!";
}

BEGIN {
   A::_erzeuge_modul();
} # BEGIN

use B;

return 1;


Ausgabe:
Code: (dl )
1
2
machdies
machdas
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
Crian
 2003-08-18 16:36
#61754 #61754
User since
2003-08-04
5866 Artikel
ModeratorIn
[Homepage]
user image
[quote=pq,18.08.2003, 14:18]warum nicht einfach den code generieren und dann ein eval()
machen? das mit dem modul erzeugen hört sich so umständlich
und unnötig an.
eval $code;
Modulname->import( 'was auch immer du importieren willst' );


ansonsten evtl. auch <!--cpan1-->CPAN: <!--cpan2--><!--cpan3--><!--cpan4-->[/quote]
Hmmm.... ich wusste nicht, dass man in eval auch Funktionen erzeugen kann. Nun wo ich die Modulvariabte zum laufen gebracht habe, werd ich die auch nehmen, zumal ich mir dann den erzeugten Code auch ansehen kann, bevor ich ihn wirklich benutze :)

Edit: Urgs... CPAN scheint man nicht zitieren zu können...\n\n

<!--EDIT|Crian|1061210232-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
SirLant
 2003-08-18 17:05
#61755 #61755
User since
2003-08-04
516 Artikel
BenutzerIn
[default_avatar]
Diese Lösungen setzen aber alle vorraus, dass man die Funktionsnamen bereits kennt, was aber wenn man die nicht kennt?
--Programming today is a race between Software Enginers striving to build bigger and better idiot-proof Programs,
and the Universe trying to produce bigger and better idiots.
So far, the Universe is winning!
Crian
 2003-08-18 18:41
#61756 #61756
User since
2003-08-04
5866 Artikel
ModeratorIn
[Homepage]
user image
Hmmm? Die Funktionen erzeuge ich doch selber. Wie meinst Du das, dass man die Namen noch nicht kennen könnte?
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
SirLant
 2003-08-18 19:12
#61757 #61757
User since
2003-08-04
516 Artikel
BenutzerIn
[default_avatar]
Nehmen wir an du hast ein Programm, welches für bestimmte Routienen, eine unbestimmte Zahl an Funktionen verwendet, diese überprüfen z.B. nen Text, da es beliebig viele Funktionen sein könnten, weißt du ja die Namen nicht, die Funktionen werden immer zum Programmstart so wie bei dir erzeugt und eingefügt.

Ich weiß, dass man es auch anderst lösen könnte, aber würde mich interressieren wie das gehen würde(falls sowas geht).
Mit symbolischen Referenzen, könnte man die Funktionsnamen ja bestimmen, indem man sie sub 1,2,3,4,usw. nennt und in ner Schleife durchläuft, oder?Aber wäre natürlich nicht die sauberste Lösung.
--Programming today is a race between Software Enginers striving to build bigger and better idiot-proof Programs,
and the Universe trying to produce bigger and better idiots.
So far, the Universe is winning!
Strat
 2003-08-18 19:29
#61758 #61758
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
hier einíge weitere Moeglichkeiten:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sub CreateFunction {
  my (&#36package, &#36functionName, @params, ...) = @_;
 
  no strict 'refs';
  *{&#36package . '::' . &#36functionName } = 
  sub {
    # content of sub, e.g.
    my @params = @_;
    print "Sub called with @params\n";
  }
  use strict 'refs'; # optional, wenn am blockende
  
} # CreateFunction

&CreateFunction('A', 'PrintIrgendwas');
&A::PrintIrgendwas(20, 30, 40);


oder auch ueber AUTOLOAD (schwierig, meistens ist wohl die obige Loesung besser):
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
sub AUTOLOAD {
  my (&#36self, @params) = @_;
  if (my (&#36subName) = &#36AUTOLOAD =~ /.*::([^:])+&#36) {
    print "Building sub &#36subName\n";

    no strict 'refs';
    *{&#36AUTOLOAD} = 
     sub { 
       my @params = @_;
       print "Sub: @params\n";
     };
    goto &#36self->&#36subName(@params);
} # AUTOLOAD


oder die IMHO beste moeglichkeit:
Du baust einen Hash, dessen Schluessel die Namen und dessen Werte Referenzen auf Subs sind, und rufst die Funktion dann ueber den Hash auf...


und jetzt sage bitte, dass er zum Problem passt :-))

ich weiss nicht, ob der Code so laeuft, habe ihn nicht getestet....\n\n

<!--EDIT|Strat|1061220646-->
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
<< |< 1 2 >| >> 16 Einträge, 2 Seiten



View all threads created 2003-08-18 15:26.