variablennamen dynamisch vergeben?
Dominique Stender
- perl
Hallo!
Ich habe ein PerlScript geschrieben, daß u.a. einen Parameterfile ausliest. Die Datei hat diesen Aufbau:
...
bcolor=#041420
textcolor=#99bbee
...
Im Script wird die Datei ausgelesen und es foglt eine ellenlange Liste von IF Abfragen:
open (pref, "$cgi_bin_path$prefs_db")
while(<pref>)
{
($namebuf, $argbuf) = split(/=/,$_);
$argbuf =~ s/\n//;
if ($namebuf eq "bgcolor") {$bgcolor = $argbuf}
if ($namebuf eq "textcolor") {$textcolor = $argbuf}
...
Jede Zeile wird also in $namebuf und $argbuf zwischengespeichert. Dann wird die komplette Liste an IF Abfragen durchgegangen und falls der entsprechende Eintrag gefunden wurde, wird eine Variable belegt, die genauso heißt wie der Wert in $namebuf.
Ist es möglich, daß ganze irgendwie in etwas ähnliches wie folgendes umzuwandeln?
open (pref, "$cgi_bin_path$prefs_db")
while(<pref>)
{
($namebuf, $argbuf) = split(/=/,$_);
$argbuf =~ s/\n//;
$[$namebuf] = $argbuf
}
Also, daß die Variablen dynamisch einen Namen bekommen, der dem Inhalt von $namebuf entspricht?
Das würde das Script _sehr_ viel kürzer machen :-))
Tnx.
Dominique
hi!
Ich habe ein PerlScript geschrieben, daß u.a. einen Parameterfile ausliest. Die Datei hat
diesen Aufbau:
...
bcolor=#041420
textcolor=#99bbee
...
Jede Zeile wird also in $namebuf und $argbuf zwischengespeichert. Dann wird die komplette
Liste an IF Abfragen durchgegangen und falls der entsprechende Eintrag gefunden wurde,
wird eine Variable belegt, die genauso heißt wie der Wert in $namebuf.
Ist es möglich, daß ganze irgendwie in etwas ähnliches wie folgendes umzuwandeln?
open (pref, "$cgi_bin_path$prefs_db")
while(<pref>)
{
($namebuf, $argbuf) = split(/=/,$_);
$argbuf =~ s/\n//;
$[$namebuf] = $argbuf
}
Also, daß die Variablen dynamisch einen Namen bekommen, der dem Inhalt von $namebuf
entspricht?
Informiere dich mal über Hashs bzw assoziative Arrays/Listen:
open PREF, "$cgi_bin_path$prefs_db";
while (<PREF>)
{
chop;
my ($name, $arg) = split /=/;
$hashname{$name} = $arg;
}
close PREF;
bye, Frank!
hi
Informiere dich mal über Hashs bzw assoziative Arrays/Listen:
open PREF, "$cgi_bin_path$prefs_db";
while (<PREF>)
{
»» chop;
»» my ($name, $arg) = split /=/;
»» $hashname{$name} = $arg;
}
close PREF;
Ich weiß zwar nicht genau, was die zeilen bewirken, aber wenn die zeile
bgcolor=#041420
eingelesen wird existiert danach jedenfalls keine variable $bgcolor. falls richtig verstanden existiert eien variable $hashname{bgcolor}.
Leider ist das Script mittlerweile fast 1000 zeilen lang und ich habe über 50 variablen, die ich ändern müßte... hab heute noch was anderes vor :-))
trotzdem danke
Dominique
hi
open PREF, "$cgi_bin_path$prefs_db";
while (<PREF>)
{
»» chop;
»» my ($name, $arg) = split /=/;
»» $hashname{$name} = $arg;
}
close PREF;Ich weiß zwar nicht genau, was die zeilen bewirken, aber wenn die zeile
bgcolor=#041420
eingelesen wird existiert danach jedenfalls keine variable $bgcolor. falls richtig verstanden existiert eien variable $hashname{bgcolor}.Leider ist das Script mittlerweile fast 1000 zeilen lang und ich habe über 50 variablen, die ich ändern müßte... hab heute noch was anderes vor :-))
Dann probiere es doch mal mit:
...
eval "$name = '$arg'";
...
Jörk
hi
Dann probiere es doch mal mit:
...
»» eval "$name = '$arg'";
...
Also mein Code sieht jetzt so aus:
...
open (pref, "$cgi_bin_path$prefs_db")
while(<pref>)
{
($name, $arg) = split(/=/,$_);
$arg =~ s/\n//;
eval "$name = '$arg'";
...
Aber es passiert noch immer nichts.
Für weitere Vorschläge bin ich _sehr_ dankbar!
MfG
Dominique
Hi,
Also mein Code sieht jetzt so aus:
...
open (pref, "$cgi_bin_path$prefs_db")
while(<pref>)
{
($name, $arg) = split(/=/,$_);
$arg =~ s/\n//;
eval "$$name = '$arg'";
Die vorhergenannte Variante mit $hash{$name}=$arg würde ich aber bevorzugen. Du sprichst die Variable dann nur nicht mit $bgcolor an, sondern mit $hash{'bgcolor'}.
Mit solchen %hash-Variablen kann man übrigens einiges anfangen, deswegen lohnt es sich, sich mal damit zu beschäftigen ;-)
Cheatah
Mit solchen %hash-Variablen kann man übrigens einiges anfangen, deswegen lohnt es sich, sich mal damit zu beschäftigen ;-)
Da hänge ich mich mal dran, zum Thema hashes ...
Ich habe gestern "mal schnell" die directory browsing-Funktion des Apache-Webservers nachprogrammiert (Fancy-Indexing, also Ausgabe vorwärts und rückwärts sortierbar nach allen Spalten durch Mausklick auf die Überschriftszeile - diese enthält einen CGI-Link auf dieselbe Funktion mit einem zusätzlichen CGI-Parameter, der das Sortierkriterium festlegt).
Dabei habe ich beim Einlesen des Verzeichnisinhalts jeweils den Wert und den Index des Eintrags für jede einzelne Spalte abgespeichert (am Beispiel des Änderungsdatums):
$datum{$wert} = $index;
@datum[$index] = $wert;
Ich habe also (gleichnamig) einen Hash und einen Array für dieselbe Datenspalte definiert; der Hash bildet Werte auf Indizes ab, der Array Indizes auf Werte.
Später kann ich das gewünschte Sortierkriterium abfragen, und falls dies das Änderungsdatum war, kann ich mit
foreach my $key (sort keys %datum)
{
$index = $datum{$key};
tu_was ($index);
}
alle Indizes meiner Einträge in der gewünschten Reihenfolge abarbeiten: Mit $datum[$index] greife ich im Array auf das passende Änderungsdatum dieses Eintrags zu (*das* könnte ich mit $key auch direkter tun), mit $groesse[$index] auf die Dateigröße desselben Eintrags usw.
Sinn der Sache war eigentlich, in diese Verzeichnisanzeige dann noch ein paar Zusatzfunktionen einzubauen. Meine Benutzer müssen beispielsweise die Möglichkeit haben, aus einem solchen Verzeichnis auch Dateien *löschen* zu können - keine sehr typische Web-Funktion, aber der Inhalt dieses Verzeichnisses wird durch Benutzer-Aktionen dynamisch erzeugt, und irgendwann wird es halt unübersichtlich ...
Cheatah, geht das irgendwie noch eleganter? (Ich hätte gern ein Äquivalent für PASCAL-records oder C-structs, um nicht zwei Variablen pro Spalte definieren zu müssen - das macht die Parameterübergabe so unhandlich ...)
hi!
(Ich hätte gern ein Äquivalent für PASCAL-records oder C-structs, um nicht zwei Variablen
pro Spalte definieren zu müssen - das macht die Parameterübergabe so unhandlich ...)
Ich bin nicht ganz sicher, ob es damit funktioniert, aber evtl. helfen dir Arrays von Hashes weiter. Zugriff erfolgt zb. über $arrayname[0]{'key'}.
bye, Frank!
(Ich hätte gern ein Äquivalent für PASCAL-records oder C-structs, um nicht zwei Variablen
pro Spalte definieren zu müssen - das macht die Parameterübergabe so unhandlich ...)
Ich bin nicht ganz sicher, ob es damit funktioniert, aber evtl. helfen dir Arrays von Hashes weiter. Zugriff erfolgt zb. über $arrayname[0]{'key'}.
Hi,
damit gewinne ich nichts. Wenn ich meine Hashes als globale Variablen halte, dann muß ich so oder so nur den index als Parameter übergeben; wenn nicht, dann muß ich immer einen Parameter pro Datenart übergeben. Der einzige Unterschied wäre, daß ich statt @datum nun @irgendwas[1] schreiben müßte - das ist nicht lesbarer.
Was ich gesucht hätte, wäre *eine* Datenart, die einen Verbund aus Variablen verschiedener Typen darstellt und mir trotzdem deren Adressierung über Namen, nicht über Indizes, erlaubt. (Ich will ja ggf. später eine weitere Spalte einfügen können und diese nicht hinten dranhängen müssen, bloß damit sich nicht alle Indizes ändern.)
Das eben können Pascal (record) und C (struct) ... Perl nicht?
hi!
Das eben können Pascal (record) und C (struct) ... Perl nicht?
Perl unterstützt keinen Record-Typ, sonst hätte ich dir ja nicht eine andere Lösung angeboten ;)
bye, Frank!
Tag Michael!
Das eben können Pascal (record) und C (struct) ... Perl nicht?
Hi hi, das kann sogar Basic, mit Type. *g*
Nun, ich habe in der perldsc-Hilfeseite folgenden Abschnitt gefunden, der Dir vielleicht weiterhilft.
------------------------
MORE ELABORATE RECORDS
Declaration of MORE ELABORATE RECORDS
Here's a sample showing how to create and use a record whose fields are of many different sorts:
$rec = {
TEXT => $string,
SEQUENCE => [ @old_values ],
LOOKUP => { %some_table },
THATCODE => &some_function,
THISCODE => sub { $_[0] ** $_[1] },
HANDLE => \*STDOUT,
};
print $rec->{TEXT};
print $rec->{LIST}[0];
$last = pop @ { $rec->{SEQUENCE} };
print $rec->{LOOKUP}{"key"};
($first_k, $first_v) = each %{ $rec->{LOOKUP} };
$answer = &{ $rec->{THATCODE} }($arg);
$answer = &{ $rec->{THISCODE} }($arg1, $arg2);
# careful of extra block braces on fh ref
print { $rec->{HANDLE} } "a string\n";
use FileHandle;
$rec->{HANDLE}->autoflush(1);
$rec->{HANDLE}->print(" a string\n");
------------------------
Es geht dann weiter mit "Declaration of a HASH OF COMPLEX RECORDS ", das kannst Du sicher auch auf Lists of complex records adaptieren.
HTH, Calocybe
hi!
Ich weiß zwar nicht genau, was die zeilen bewirken, aber wenn die zeile
Deshalb sagte ich auch, informiere dich über Hashs.
bgcolor=#041420
eingelesen wird existiert danach jedenfalls keine variable $bgcolor. falls richtig verstanden
existiert eien variable $hashname{bgcolor}.
Nicht ganz: $hashname['bgcolor'}
Leider ist das Script mittlerweile fast 1000 zeilen lang und ich habe über 50 variablen, die ich
ändern müßte... hab heute noch was anderes vor :-))
Über sowas macht man sich Gedanken, bevor man anfängt zu programmieren. Hast du keinen Editor mit Suchen und Ersetzen-Funktion?
bye, Frank!