Markus Trusk: Wert aus einer Schleife heraus ändern?

Hi,
Ich bin momentan bei einem Problem, das mir einfach erschien, aber anscheinend doch nicht so einfach ist, oder vielleicht steht ich auch nur auf der Leitung. Ich habe 5 Variablen, die Werte enthalten können, oder leer sind. Alle Variablen, die leer sind, wurde ich gerne so abändern, dass sie stattdessen ein %-Zeichen enthalten. Zuerst dachte ich irgendwie an so etwas:

my $i = 0;
foreach ($label,$artist,$title,$style,$quality)    {
         if ($_ =~ /^\s*$/)    {
         $_[$i] = '%';
         }
$i++;
}

Aber hiermit kann ich die Werte nicht ändern. Ich dachte auch an Referenzen, aber kann ich die hier überhaupt einsetzen, und wenn ja wie?

Markus Trusk.

  1. hallo,

    $_[$i] = '%';

    es muss $_ = [...] heissen, weil $_ hier der aktuell durch die schleife "angesteuerte" variable entspricht.

    gruss

    --
    no strict; no warnings; Selbstcode: (*) ^_^ ( . ) ( . ) :-(bla)
  2. Hi,

    my $i = 0;
    foreach ($label,$artist,$title,$style,$quality)    {
             if ($_ =~ /^\s*$/)    {
             $_[$i] = '%';
             }
    $i++;
    }

    Machs besser so:

    foreach my $x ($label,$artist,$title,$style,$quality) {
       if( $x =~ /^\s+$/ ){ $x = '%' }
    }

    Gruss, Rolf

    --
    SELFforum - Das Tor zur Welt!
    Theoretiker: Wie kommt das Kupfer in die Leitung?
    Praktiker: Wie kommt der Strom in die Leitung?
    1. Hi,

      foreach my $x ($label,$artist,$title,$style,$quality) {
         if( $x =~ /^\s+$/ ){ $x = '%' }
      }

      danke, aber wäre es nicht effizienter, keine extra Variable, sprich $x dafür zu definieren? Desweiteren heißt $x =~ /^\s+$/ doch mindestens ein Leerzeichen, aber wenn ein Benutzer überhaupt nichts eingibt, wird gar nichts in der Variable gespeichert, nicht mal ein Leerzeichen, somit muss ich * statt + verwenden. (Ich bin hierbei nämlich schon mal reingefallen).
      Jedenfalls funktioniert es jetzt, danke euch beiden.

      Markus Trusk.

      1. Hi Markus,

        danke, aber wäre es nicht effizienter, keine extra Variable, sprich $x dafür zu definieren? Desweiteren heißt $x =~ /^\s+$/ doch

        Nunja, $_ ist $_ und da wird nicht dranrum geschrieben ;-)

        mindestens ein Leerzeichen, aber wenn ein Benutzer überhaupt

        Besser ist es, die Leerzeichen vorn und hinten rauszunehmen
        http://perlbase.xwolf.de/cgi-bin/perlbase.cgi?display=7.2&id=4

        und dann schauen ob von $x noch was übrig ist: if $x ...

        Gruss, Rolf

        --
        SELFforum - Das Tor zur Welt!
        Theoretiker: Wie kommt das Kupfer in die Leitung?
        Praktiker: Wie kommt der Strom in die Leitung?
        1. hallo

          Nunja, $_ ist $_ und da wird nicht dranrum geschrieben ;-)

          ist nicht in dem fall das $x dasselbe wie $. perl stellt doch $ automatisch bereit ?

          oder wie?

          gruss

          --
          no strict; no warnings; Selbstcode: (*) ^_^ ( . ) ( . ) :-(bla)
          1. hallo

            Nunja, $_ ist $_ und da wird nicht dranrum geschrieben ;-)
            ist nicht in dem fall das $x dasselbe wie $_.
            perl stellt doch $_ automatisch bereit ?

            Freilich. Es geht ja auch, sogar mit strict.

            use strict;
            my ($x, $y , $z);
            foreach($x,$y,$z){ $_ = 'otto'}
            print join "\n", $x,$y,$z;

            Aber es ist ein schlechter Style. Und wer schonmal mit $_ ein aha-Erlebnis hatte, wird es in Zukunft vermeiden, PERL eigenen Variablen irgendwelche Werte zuzuweisen.

            Gruss, Rolf

            --
            SELFforum - Das Tor zur Welt!
            Theoretiker: Wie kommt das Kupfer in die Leitung?
            Praktiker: Wie kommt der Strom in die Leitung?
        2. Hi,

          Besser ist es, die Leerzeichen vorn und hinten rauszunehmen
          http://perlbase.xwolf.de/cgi-bin/perlbase.cgi?display=7.2&id=4

          Ja, das kenne ich und verwende es auch häufig, aber ich finde es trotzdem effizienter und besser, wenn ich prüfe, ob die Variable nur aus Leerzeichen besteht oder gar nichts darin ist. Wenn ich zuerst vorne und hinten die Leerzeichen weglösche, und dann nochmal überprüfe, ob die Variable leer ist, kann ich doch gleich an Anfang überprüfen, ob die Variable leer ist und erspar mir einen reg. Ausdruck. :)

          Markus Trusk.

  3. Hi,

    my $i = 0;
    foreach ($label,$artist,$title,$style,$quality)    {
             if ($_ =~ /^\s*$/)    {
             $_[$i] = '%';
             }
    $i++;
    }

    das ist ein typischer "Schlauchsteher" ;-) die Variable $i ist überflüssig, da innerhalb der Schleife $_ eine Referenz auf die aktuelle Variable enthält. Alle Änderungen an $_ innerhalb der Schleife werden an der eigentlichen Variable durchgeführt. So müsste Dein Code funktionieren:

    foreach ($label,$artist,$title,$style,$quality)    {
             if ($_ =~ /^\s*$/)    {
                  $_ = '%';
             }
    }

    viele Grüße
      Achim Schrepfer

    --
    http://reskit.speedesign.de/ - PHP-Bibliothek zum automatischen Erzeugen von HTML-Tabellen, -Formularen und -Baummenüs anhand von MySQL-Tabellen
    Selfcode: sh:) fo:| ch:| rl:° br:> n4:{ ie:% mo:} va:| de:< zu:| fl:( ss:) ls:& js:|
    1. Hi,

      So müsste Dein Code funktionieren:

      foreach ($label,$artist,$title,$style,$quality)    {
               if ($_ =~ /^\s*$/)    {
                    $_ = '%';
               }
      }

      Ja, das tut er, ich habe es bereits dorthin geändert. Manchmal denke ich einfach zu kompliziert, obwohl dei Lösung auf der Hand liegt. :)

      Markus Trusk.

      1. Hi,

        Ja, das tut er, ich habe es bereits dorthin geändert. Manchmal denke ich einfach zu kompliziert, obwohl dei Lösung auf der Hand liegt. :)

        das gibt es oft. Programmierer sehen häufiger den Wald vor lauter Bäumen nicht. Da hilft meist nur ein wenig Abstand von der Sache nehmen, ne Stunde mal was anderes machen und dann das Problem noch mal ganz ruhig aufdröseln...

        viele Grüße
          Achim Schrepfer

        --
        http://reskit.speedesign.de/ - PHP-Bibliothek zum automatischen Erzeugen von HTML-Tabellen, -Formularen und -Baummenüs anhand von MySQL-Tabellen
        Selfcode: sh:) fo:| ch:| rl:° br:> n4:{ ie:% mo:} va:| de:< zu:| fl:( ss:) ls:& js:|
  4. my $i = 0;
    foreach ($label,$artist,$title,$style,$quality)    {
             if ($_ =~ /^\s*$/)    {
             $_[$i] = '%';
             }
    $i++;
    }

    Um Benutzereingaben zu prüfen, würd ich sowas nicht machen. regExpressions sind in dem Falle overkill.

    Falls du die Einagben mit dem CGI Modul holst, dann würde ich sowas machen um die Warnungen zu vermeiden:

    my $label = CGI::param('label') || '';

    oder halt:

    my $label = CGI::param('label') || '%';

    Was aber schlecht ist. wenn du überprüfen willst ob der Benutzer was eingegeben hat:

    my $label = CGI::param('label');

    if(!$label) print "Angabe fehlt";

    Falls ein Leerstring erlaubt ist:

    if(!defined $label) print "Angabe fehlt komplett";

    Struppi.

    1. Hi,

      my $label = CGI::param('label');
      if(!$label) print "Angabe fehlt";
      Falls ein Leerstring erlaubt ist:
      if(!defined $label) print "Angabe fehlt komplett";

      Also ich habe das jetzt mal kurz nachsimuliert, aber wenn ich so etwas schreibe:

      my $string = '          ';

      und if(!defined $label) oder if(!$label) darauf anwende, geht der String schon nicht mehr als leerer String durch. Solche Tricks der Benutzer will ich natürlich unterbinden.
      Es funktioniert übrigens nur, wenn der String keiner ist, also ''.

      Markus Trusk.

      1. Also ich habe das jetzt mal kurz nachsimuliert, aber wenn ich so etwas schreibe:

        my $string = '          ';

        und if(!defined $label) oder if(!$label) darauf anwende, geht der String schon nicht mehr als leerer String durch. Solche Tricks der Benutzer will ich natürlich unterbinden.
        Es funktioniert übrigens nur, wenn der String keiner ist, also ''.

        Also. Wenn du die Eingabe von CGI skripten prüfen willst, ist der Parameter undefined wenn nichts in einem Textfeld eingegeben wurde. Wenn Leerzeichen eingeben wurden, ist er natürlich nicht mehr undefined und auch nicht leer.

        Wenn du solche Eingaben verhindern willst, solltest du dies dort prüfen, wo du mit den Variabeln arbeitest, sonst blickst du nämlich irgendwann nicht mehr durch, was du wo mit ihnen machst.

        Ich würde eine Funktion schreiben (die nebenbei bemerkt ständig gebraucht wird, daher in so 'ne Art Standardmodul rein sollte), die die Leerzeichen stript.

        entweder:

        sub trim
        {
        $_[0] =~ s/^\s+//;
        $_[0] =~ s/\s+$//;
        $_[0];
        }

        oder flexibler:

        sub trim{return rtrim(ltrim($_[0]));}
        sub rtrim{$_[0] =~ s/\s+$//;$_[0];}
        sub ltrim{$_[0] =~ s/^\s+//;$_[0];}

        und dann die entsprechende Funktion aufrufen, wenn du die Eingabe bearbeitest und die Gültigkeit prüfst.

        Eine Eingabe direkt am Anfang abändern kann u.U. später langwierige Fehlersuche nach sich ziehen.

        Struppi.

        1. Hallo Struppi,

          sub trim
          {
          $_[0] =~ s/^\s+//;
          $_[0] =~ s/\s+$//;
          $_[0];
          }

          Wah! Böse Falle, ganz böse Falle.

          sub trim {
            my $val = shift;

          $val =~ s/^\s+//;
            $val =~ s/\s+$//;

          return $val;
          }

          @_ enthält automagische Referenzen auf die Orginal-Variable. Niemals @_ direkt bearbeiten,
          es sei denn, man hat es *deutlichst* dokumentiert.

          Grüße,
           CK

          --
          Mit einem Windhauch kannst du das Feuer loeschen. Mit einem Windhauch kannst du das Feuer entfachen.