Christoph Schnauß: Zeichenkettenverknüpfung in einer Variablen

guten Abend Forum ;-)

Ich bin grade am Basteln für eine etwas umfangreichere Konstruktion (manche Leute nennen sowas ein "Projekt") mit mehreren Abfrageformularen, unter anderem darf man (muß man aber nicht) da auch eine mail-Adresse oder einen URL eintragen. Natürlich muß mein Script nachschauen, ob die Formularfelder irgendwelche Werte enthalten und entsprechend reagieren. Das tut es in folgender Weise:
  if ($email) {
  $absender = $cgi->b($name). ", ".
              $cgi->img({-border =>'0',
                         -src =>$iconurl.'/mail.gif'}).
              " ".
              $cgi->a({-href =>'mailto:'.$email}).$email
  } else {
  $absender = $cgi->b($name)
  }

Das Ding funktioniert recht gut, das heißt, ich kann meine neue Variable "$absender" so einsetzen wie gewünscht, und das Prinzip funktioniert auch mit weiteren Formularfeldern und zugehörigen Variablen.

Ich habe allerdings ein paar Stunden und ein paar hundert Fehlermeldungen gebraucht, bis ich wußte, daß und wo ich hier zur Zeichnkettenverknüpfung Punkte brauche anstelle von Kommas  -  und es ist ja auch noch ein Komma drin stehengeblieben in dem ganzen Konstrukt (das in ", " enthaltene Komma hat keine Funktion, sondern wird ausgegeben). Das macht mich etwas nachdenklich  -  daß ein Script "funktioniert" und es keine Fehlermeldungen mehr gibt, muß ja eben noch nicht heißen, daß es auch "optimal gestaltet" ist. Wie ist das nun mit dem Verhältnis von Punkt und Komma in so einer Konstruktion?

Grüße aus Berlin

Christoph S.

  1. Ich habe allerdings ein paar Stunden und ein paar hundert Fehlermeldungen gebraucht, bis ich wußte, daß und wo ich hier zur Zeichnkettenverknüpfung Punkte brauche anstelle von Kommas  -  und es ist ja auch noch ein Komma drin stehengeblieben in dem ganzen Konstrukt (das in ", " enthaltene Komma hat keine Funktion, sondern wird ausgegeben). Das macht mich etwas nachdenklich  -  daß ein Script "funktioniert" und es keine Fehlermeldungen mehr gibt, muß ja eben noch nicht heißen, daß es auch "optimal gestaltet" ist. Wie ist das nun mit dem Verhältnis von Punkt und Komma in so einer Konstruktion?

    das hatte ich in deinem letzten Problem schonmal angedeutet und dir gesagt du solltst den Punkt als Stringverknüpfer verwenden, da das Komma eine Liste trennt. D.H. wenn die Funktion eine Liste als Parameter erwartet wird irgendwas anderes passieren wenn du die Strings mit dem Komma verknüpst, was eigentlich nur bei print gehen sollte.

    Struppi.

    1. hallo Struppi,

      das hatte ich in deinem letzten Problem schonmal angedeutet und dir gesagt du solltst den Punkt als Stringverknüpfer verwenden

      Richtig, bloß war das "damals" in einem etwas anderen Zusammenhang

      da das Komma eine Liste trennt.

      "theoretisch" weiß ich das auch bzw. kanns nachlesen. _praktisch_ falle ich immer mal wieder auf die Nase, wenn so eine Variable, wie im Beispiel angegeben, hinterher in runden (), geschweiften {} oder eckigen [] Klammern weiterverarbeitet wird.

      [...] was eigentlich nur bei print gehen sollte.

      Das tuts in diesem Fall auch  -  teilweise. Je nach "if" wird entweder mit "print" etwas ausgegeben oder der Variableninhalt weiterverarbeitet.

      Die "Glaubensfrage", die du oben noch angesprochen hast, ist tasächlich eine. Mir fällt es leichter, das (rechte) Ende einer Zeile zu überprüfen, weil ich da insbesondere bei der Verwendung von Komma und Semikolon auch noch gelegentlich Probleme habe. Dem Interpreter ist das allerdings wurscht, wo er diese Zeichen findet, Hauptsache, sie sind vorhanden  -  und sie sind "richtig".

      Grüße aus Berlin

      Christoph S.

      1. das hatte ich in deinem letzten Problem schonmal angedeutet und dir gesagt du solltst den Punkt als Stringverknüpfer verwenden
        Richtig, bloß war das "damals" in einem etwas anderen Zusammenhang

        jaja, aber dadurch können halt Probleme entstehen auf die ich dich damals schon aufmerksam machen wollte.

        da das Komma eine Liste trennt.
        "theoretisch" weiß ich das auch bzw. kanns nachlesen. _praktisch_ falle ich immer mal wieder auf die Nase, wenn so eine Variable, wie im Beispiel angegeben, hinterher in runden (), geschweiften {} oder eckigen [] Klammern weiterverarbeitet wird.

        Das spielt an sich keine Rolle. Mit Komma getrennte Werte sind erstmal ein Liste, allerdings ist Perl oft zu schlau und versucht halt was sinnvolles aus einer Liste zu machen und verknüpft sie dann halt, wenn es nicht anders geht. Ich verwende auch bei print mittlerweile keine Kommas mehr.

        Dein Konkretes Problem ist, das du Funktionen aus CGI.pm verwendest, die teilweise sehr flexibel mit den Parametern umgehen könne. Du kannst die einfache Form nehmen mit einer Liste von Paramtern in einer bestimmten Reihenefolge oder mit Referenzen auf Datenstrukturen, womit die Funktion dann versucht etwas sinnvolles anzufangen. wenn du jetzt Strings übergeben willst und diese Verknüpfst wirst du mit der Komma version schnell Probleme kriegen (die du ja hattest - aber keine Sorge ich hatte die auch ;-) )

        [...] was eigentlich nur bei print gehen sollte.
        Das tuts in diesem Fall auch  -  teilweise. Je nach "if" wird entweder mit "print" etwas ausgegeben oder der Variableninhalt weiterverarbeitet.

        naja, du verknüfst hier ja nur einen String, der danach wohl irgendwann ausgegeben wird.

        Die "Glaubensfrage", die du oben noch angesprochen hast, ist tasächlich eine. Mir fällt es leichter, das (rechte) Ende einer Zeile zu überprüfen, weil ich da insbesondere bei der Verwendung von Komma und Semikolon auch noch gelegentlich Probleme habe. Dem Interpreter ist das allerdings wurscht, wo er diese Zeichen findet, Hauptsache, sie sind vorhanden  -  und sie sind "richtig".

        richtig ist beides, das stimmt. Mir gings in erster Linie um die Stringverknüpfung und wenn man diese über mehrere Zeilen macht läßt sich die Gültigkeit IMHO leichter nachverfolgen mit dem Punkt vorne.

        Struppi.

        1. hallo Struppi,

          da das Komma eine Liste trennt.
          "theoretisch" weiß ich das auch bzw. kanns nachlesen. _praktisch_ falle ich immer mal wieder auf die Nase, wenn so eine Variable, wie im Beispiel angegeben, hinterher in runden (), geschweiften {} oder eckigen [] Klammern weiterverarbeitet wird.
          Das spielt an sich keine Rolle.

          Doch  -  jedenfalls beim debugging. Die Fehlermeldungen, die ich kriege, verweisen mich nämlich nicht auf die Zeile, in der ich meine Variable definiere, sondern auf die Zeile, in der meine Variable verarbeitet wird.

          Dein Konkretes Problem ist, das du Funktionen aus CGI.pm verwendest, die teilweise sehr flexibel mit den Parametern umgehen könne.

          Möglich.

          Du kannst die einfache Form nehmen mit einer Liste von Paramtern in einer bestimmten Reihenefolge

          Richtig, das "kann" ich, aber genau das "will" ich nicht. Ich gebe zu, daß ich mit CGI.pm das eine oder andre Problem habe, aber ich weiß von diesem Modul inzwischen genug, um den Ehrgeiz zu entwickeln, es eben nicht mit "einfacheren Formen" zu versuchen.

          Grüße aus Berlin

          Christoph S.

  2. wo ich schon mal dabei bin.

    if ($email) {
      $absender = $cgi->b($name). ", ".
                  $cgi->img({-border =>'0',
                             -src =>$iconurl.'/mail.gif'}).
                  " ".
                  $cgi->a({-href =>'mailto:'.$email}).$email
      } else {
      $absender = $cgi->b($name)
      }

    ich hab die Punkte früher auch immer so gesetzt, kann dir aber deshalb sagen es ist praktischer die Punkte vorne zu setzten (ist aber vermutlich eine Glaubensfrage), da du diese nicht so leicht übersiehst wie wenn sie hinten stehen.

    Also etwa so:

    $absender = $cgi->b($name). ", "
                  . $cgi->img({-border =>'0', -src =>$iconurl.'/mail.gif'})
                  . " "
                  . $cgi->a({-href =>'mailto:'.$email})
                  . $email

    aber wie gesagt nur meine Erfahrung.

    Struppi.

  3. ja auch noch ein Komma drin stehengeblieben in dem ganzen Konstrukt (das in ", " enthaltene Komma hat keine Funktion, sondern wird ausgegeben). Das macht mich etwas nachdenklich  -  daß ein Script "funktioniert" und es keine Fehlermeldungen mehr gibt, muß ja eben noch nicht heißen, daß es auch "optimal gestaltet" ist. Wie ist das nun mit dem Verhältnis von Punkt und Komma in so einer Konstruktion?

    Meine IMHO sehr einfach:
    Das Komma steht in " " damit hast Du einen String.
    Du verknüpfst es also mit Deinen Variablen zu einer Zeichenkette.
    Wenn Du die "" wegläst dürfte ne Fehlermeldung kommen.
    Irgenwas in der Art wie unerwartetes Zeichen oder so!

    Viele Grüße aus dem nächtlichen Karlshorst nach Mitte!

    TomIRl

    1. hallo Tom,

      Das Komma steht in " " damit hast Du einen String.

      ... der ausgegeben werden soll, deshalb steht es _innerhalb_ der Anführungszeichen. Es hat mit dem String, der die Variable bildet, aber nichts zu tun.

      Wenn Du die "" wegläst dürfte ne Fehlermeldung kommen.

      Nein. Das ist ja lediglich dazu da, daß die einzelnen Wörter, die ich am Bildschirm sehe oder in eine Datei schreibe, nicht "aneinander kleben".

      Grüße aus Berlin

      Christoph S.

  4. hi!

    Wie ist das nun mit dem Verhältnis von Punkt und Komma in so einer
    Konstruktion?

    Wenn ich dich richtig verstanden habe, ist dir der Unterschied
    zwischen Komma- und Punkt-Operator in Perl nicht ganz klar. Und was
    macht man in so einem Fall? Richtig, man schaut in die perldoc:

    === cut ===
           Additive Operators

    Binary "+" returns the sum of two numbers.

    Binary "-" returns the difference of two numbers.

    Binary "." concatenates two strings.

    [...]

    Comma Operator

    Binary "," is the comma operator.  In scalar context it
           evaluates its left argument, throws that value away, then
           evaluates its right argument and returns that value.  This
           is just like C's comma operator.

    In list context, it's just the list argument separator,
           and inserts both its arguments into the list.

    The => digraph is mostly just a synonym for the comma
           operator.  It's useful for documenting arguments that come
           in pairs.  As of release 5.001, it also forces any word to
           the left of it to be interpreted as a string.
    === cut ===

    bye, Frank!

    --
    Never argue with an idiot. He will lower you to his level and then
    beat you with experience.
    1. morgens,

      Wenn ich dich richtig verstanden habe, ist dir der Unterschied
      zwischen Komma- und Punkt-Operator in Perl nicht ganz klar

      Jaein. _Theoretisch_ kenne ich ihn, auch weil ich perldoc natürlich ziemlich sehr gründlich nachgelesen habe. Aber _praktisch_ falle ich dabei gelegentlich auf die Nase.

      Ein zweites Beispiel:
      print NEU $cgi->Tr($cgi->td({-width =>'12%',
                                   -style =>'border: 1 solid #0C0C0C',
                                   -valign =>'top',
                                   -align =>'center'},
                                   $cgi->a({-href => $basisurl.'/faq.htm'}).'FAQ</a><br />'.
                                   $cgi->a({-href => $basisurl.'/archiv.htm'}).'Archiv</a><br />'.
                                   $cgi->a({-href => $basisurl.'/script.txt'.
                                            -target =>'_blank'}).'Source</a>'), "\n",

      Wenn ich hier hinter "'center'}" einen Punkt setze, erhalte ich in der Bildschirmausgabe Murks, das heißt, ich kriege eine Anzeige "CGIHash231467" oder ähnlich. Da _muß_ also das Komma hin.

      Mein Problem ist eher, daß mir nicht klar ist, wann ich eine "Liste" schreibe, und wann etwas anderes. Ich muß im Moment noch nach der Methode "Try and Error" vorgehen, was etwas mühsam ist.

      Grüße aus Berlin

      Christoph S.

      1. hi!

        print NEU $cgi->Tr($cgi->td({-width =>'12%',
                                     -style =>'border: 1 solid #0C0C0C',
                                     -valign =>'top',
                                     -align =>'center'},
                                     $cgi->a({-href => $basisurl.'/faq.htm'}).'FAQ</a><br />'.
                                     $cgi->a({-href => $basisurl.'/archiv.htm'}).'Archiv</a><br />'.
                                     $cgi->a({-href => $basisurl.'/script.txt'.
                                              -target =>'_blank'}).'Source</a>'), "\n",

        Wenn ich hier hinter "'center'}" einen Punkt setze, erhalte ich in
        der Bildschirmausgabe Murks, das heißt, ich kriege eine Anzeige
        "CGIHash231467" oder ähnlich. Da _muß_ also das Komma hin.

        Ist ja klar, dass dabei nichts richtiges rauskommt. Der Punkt dient
        nur dazu, zwei Strings aneinander zu hängen. Das was du aber dann vor
        dem Punkt stehen hattest, war ein Hash. Also passieren undefinierte
        Dinge.

        Mein Problem ist eher, daß mir nicht klar ist, wann ich eine
        "Liste" schreibe, und wann etwas anderes. Ich muß im Moment noch
        nach der Methode "Try and Error" vorgehen, was etwas mühsam ist.

        In "perldoc perldata" ist das wichtigste zu Kontexten beschrieben. Im
        Grunde muss man vor allem zwei Fälle unterscheiden: wendet man eine
        Funktion an, kann ein Parameter entweder als Skalar oder als Liste
        erwartet werden -- dementsprechend wird der Kontext gesetzt. Welcher
        Typ erwartet wird, ist in "perldoc perlfunc" bei der entsprechenden
        Funktion beschrieben. (Das ganze wird dadurch etwas erschwert, dass
        Perl Skalara u.U. automatisch in Listen umwandelt.)

        Der zweite wichtige Fall ist eine Zuweisung: in der Situation hängt
        der Kontext auf der rechten Seite des =-Zeichens ab vom Kontext auf
        der linken Seite der Zuweisung, also prinzipiell davon, ob du den
        Wert einem Skalar oder einer Liste (oder einem Hash) zuweist.

        bye, Frank!

        --
        Never argue with an idiot. He will lower you to his level and then
        beat you with experience.
      2. morgens,

        Wenn ich dich richtig verstanden habe, ist dir der Unterschied
        zwischen Komma- und Punkt-Operator in Perl nicht ganz klar
        Jaein. _Theoretisch_ kenne ich ihn, auch weil ich perldoc natürlich ziemlich sehr gründlich nachgelesen habe. Aber _praktisch_ falle ich dabei gelegentlich auf die Nase.

        Ein zweites Beispiel:
        print NEU $cgi->Tr($cgi->td({-width =>'12%',
                                     -style =>'border: 1 solid #0C0C0C',
                                     -valign =>'top',
                                     -align =>'center'},
                                     $cgi->a({-href => $basisurl.'/faq.htm'}).'FAQ</a><br />'.
                                     $cgi->a({-href => $basisurl.'/archiv.htm'}).'Archiv</a><br />'.
                                     $cgi->a({-href => $basisurl.'/script.txt'.
                                              -target =>'_blank'}).'Source</a>'), "\n",

        Wenn ich hier hinter "'center'}" einen Punkt setze, erhalte ich in der Bildschirmausgabe Murks, das heißt, ich kriege eine Anzeige "CGIHash231467" oder ähnlich. Da _muß_ also das Komma hin.

        Der Code stimmt auch nicht. Da sind einige Fehler drin.
        Ich verstehe wirklich nicht warum meine Erklärungen so unverständlich waren :-(

        Du hast hier eine Reihe von Funktionen mit Parametern, diese trennst du mit einem Komma und einige Paramter davon sind Strings und diese fügst du mit dem Punkt zusammen. Ist doch ganz einfach (finde ich)

        OK, gehen wir es mal zusammen durch

        print(  # Funktion
         $cgi->Tr( # Funktion
          $cgi->td(
           # 1. Paramter (HASH Referenz)
           {
             -width =>'12%',
             -style =>'border: 1 solid #0C0C0C',
             -valign =>'top',
             -align =>'center'
           },
           # 2. Parameter
           $cgi->a( # Funktion
            # 1. Parameter
            {
              -href =>
                # hier verknüfst du den wert
                $basisurl
                .'/faq.htm'
            } # ende 1. Parameter von cgi->a
            # 2. Parameter von cgi->
            , 'FAQ<br />'
           ) # ende von Funktion cgi->a

        . '<br />'

        . $cgi->a( {-href => $basisurl.'/archiv.htm'}, 'Archiv' ) # so sieht das kurz aus.

        .'<br />'

        . $cgi->a(
                {
                   -href => $basisurl.'/script.txt'
                   , # !!! Der Punkt war falsch!!!! da muss ein Komma hin
                   -target =>'_blank'
                }
                , 'Source'
             )
           # Hier ist der String zu Ende
           )
          ) # Ende von td
         ) # Ende von Tr
         . "\n"
         # und hier solltest du wie ich schon mehrmals schrieb
         # einen Punkt verwenden damit du weiß was du willst.
        ;

        vielleicht hilft dir das mehr, weil dein Code war wirklich umständlich und teilweise falsch.

        struppi.

        1. hi,

          vielleicht hilft dir das mehr, weil dein Code war wirklich umständlich und teilweise falsch.

          Ich lerne halt ein bissel langsam  -  vor allem, wenn ich älteren "funktionierenden" Code auf die Benutzung des CGI-Moduls umstellen will. Und: ja, natürlich war mein Code "teilweise falsch und umständlich", deshalb knabbere ich ja daran herum und versuche ihn zu korrigieren. Trotz eben teilweise falscher Verwendung der Operatoren bekomme ich aber nicht alles im log als Fehler angekreidet, sonst käme ich alleine weiter.

          Aber ich müßte jetzt erstmal genügend Hinweise haben, danke.

          Grüße aus Berlin

          Christoph S.