Schrift
[thread]12374[/thread]

String interpretieren, Variable in Variable

Leser: 1


<< |< 1 2 >| >> 18 Einträge, 2 Seiten
dasa
 2008-08-19 12:59
#113681 #113681
User since
2008-08-19
4 Artikel
BenutzerIn
[default_avatar]
Hallo zusammen,

gleich zu meiner Entschuldigung, ich programmiere z.Z. an einem TWiki Plugin, und dies verwendet teilweise unschöne Syntax, und genau diese ist auch die Quelle meines Problems:

Also erstmal lese ich vom System einen String ein:

Code (perl): (dl )
1
2
3
4
5
6
7
8
my $output = &TWiki::Func::getPreferencesValue( "MYPLUGIN_OUTPUT" );

# Dies hat den Inhalt:
# __[[$MYWEB][$MYTOPIC]]__
# nun wird im System gerade die beiden Variablen auch gesetzt

my $MYWEB = "TWiki";
my $MYTOPIC = "WebHome";


Nun die Frage (wohl schon einigen nach dem Beispiel klar), ich möchte nun gern dass der Output- String die Variablen selbst interpretiert, ohne dass ich mit Regex zur Hand muss.

Also irgendwas wie
Code (perl): (dl )
1
2
$output = do something with $output; 
print $output; # Gibt dann __[[TWiki][WebHome]]__



Nun fragt ihr euch, warum schreibt er nicht nen Regex für die beiden Fälle, oder, noch besser, das ganze gelöst mit einem Hash, hab ich nun auch, aber vielleicht gibt es in Perl eine Lösung dies noch kürzer zu machen. Der Workaround:

Code (perl): (dl )
1
2
3
4
$varHash{WEB} = &TWiki::Func::getPreferencesValue( "WEB" );
$varHash{TOPIC} = &TWiki::Func::getPreferencesValue( "TOPIC" );
...
$output =~ s/\$(\w+)/$varHash{$1}/mg;
Gast Gast
 2008-08-19 13:18
#113682 #113682
hoert sich ein bisschen nach eval an :)
LanX-
 2008-08-19 13:22
#113683 #113683
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
Du willst dass die Variablen in '__[[$MYWEB][$MYTOPIC]]__' interpoliert werden ???

$ergebnis="__[[$MYWEB][$MYTOPIC]]__";

wenn zum Zeitpunkt der Kompilierung das Template nicht bekannt ist, kannst du mit eval oder dem e-Modifier in s/// arbeiten, aber Vorsicht vor Sicherheitslücken!
LanX-
 2008-08-19 13:43
#113684 #113684
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
ich weiß aber nicht obs eleganter geht:
Code (perl): (dl )
 $output= eval "\"$output\""
dasa
 2008-08-19 13:50
#113685 #113685
User since
2008-08-19
4 Artikel
BenutzerIn
[default_avatar]
Danke, funktioniert!

Zwar werde ich aus Sicherheitsgründen auf die Hash- Variante zurück greifen, aber trotzdem vielen Dank fürs Beispiel, hab zwar auch mit eval herumgespielt, aber auf die Variante mit "\" bin ich nicht gekommen, hab bei eval eindeutig nachholbedarf, ist mir teilweise noch suspekt.
LanX-
 2008-08-19 14:02
#113686 #113686
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
der Vollständigkeit halber
Code (perl): (dl )
$output=~s/\$(\w+)/$$1/eg;


Sicherheitslücke? laut Betterworld kann bei einem /e nicht viel passieren ...
LanX-
 2008-08-19 14:18
#113687 #113687
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
Interessant, man kann sogar auf das /e verzichten ... : )
Code (perl): (dl )
$output=~s/\$(\w+)/$$1/g;


die rechte Seite ist laut Doku in "perl-think" doublequoted, deswegen wird nach der Einsetzung von $1 eine Variableninterpolation durchgeführt ...

Hmm komischerweise scheint das aber nicht für alle Matchvariablen zu gelten, z.B. $&.
dasa
 2008-08-19 15:05
#113697 #113697
User since
2008-08-19
4 Artikel
BenutzerIn
[default_avatar]
Danke LanX, nun haben wir sehr viele elegante Lösungen für das Problem! Nächstes mal wird ja schon fast das Auswählen schwer.
LanX-
 2008-08-19 15:09
#113698 #113698
User since
2008-07-15
1000 Artikel
BenutzerIn

user image
hmm bei der letzten Lösung ist mir der mechanismus aber nicht klar ... eventuell ist es auch symbolisches Dereferenzieren, dann sollte es aber nicht mehr strict sein !?!

NACHTRAG: wie befürchtet nicht strict weil symbolisches Dereferenzieren (aha!)
Can't use string ("w") as a SCALAR ref while "strict refs" in use ...

hmm das man den perldebugger nicht auf strict setzen kann ist auch blöd...
Struppi
 2008-08-19 16:01
#113705 #113705
User since
2006-02-17
628 Artikel
BenutzerIn
[Homepage]
user image
Naja, wenn man weiß was man tut kann man strict ja auch auschalten
Code (perl): (dl )
no strict 'refs'

ist genau für so Fälle da.
<< |< 1 2 >| >> 18 Einträge, 2 Seiten



View all threads created 2008-08-19 12:59.