HP-User: Syntaxproblem bei Pfeilfunktion

Abend Forum:

Hier muss irgend etwas falsch sein:

  
while (my $row = $sth->fetchrow_hashref){  
                                        print("name = $row->{Name}  'contact = $row->{Contact}"."\n";  
                                        }  

Wie kommen die Anführungszeichen bzw die einzelnen Apostrophstriche hin?

Gruss HP-User

  1. Tach!

    while (my $row = $sth->fetchrow_hashref){

    print("name = $row->{Name}  'contact = $row->{Contact}"."\n";
    }

    
    > Wie kommen die Anführungszeichen bzw die einzelnen Apostrophstriche hin?  
      
    Das kann nur in Abhängigkeit vom Ausgabekontext beantwortet werden. Und den hast du nicht genannt.  
      
      
    dedlfix.
    
    1. Abend dedlfix

      Perlcode:

        
      #!/usr/bin/perl  
        
      # sollte in keinem Script fehlen  
      use strict;  
      use warnings;  
        
      # DBI Modul Laden  
      use DBI;  
        
      # Verzeichnis mit dem Script finden.  
      # "." muss nicht immer das Verzeichnis mit dem Script sein  
      use FindBin '$Bin';  
        
      # Sollte man machen.  
      # es hilft die Dateinamen  
      # von den Tabellennamen zu trennen.  
      my %zuordnung=(  
                    prospects => {  
                    file => 'prospects.csv',  
                    col_names   => ['Name', 'Address', 'Floors', 'Donated last year', 'Contact'],  
                    },  
                    );  
        
      # Verbindung aufbauen  
      my $dbh = DBI->connect("DBI:CSV:", undef, undef, {  
                                                        # Zeilenseparator  
                                                        csv_eol => "\x0A",  
                                                        # Spaltenseparator:  
                                                        csv_sep_char => ",",  
                                                        # Verzeichnis mit den Dateien  
                                                        f_dir => $Bin,  
                                                        # Zuordnung Dateiname -> Tabelle  
                                                        csv_tables => \%zuordnung,  
                                                        # bei Fehlern immer sterben:  
                                                        RaiseError => 1,  
                                                        }  
                            ) or die($DBI::errstr);  
        
      # Testausgabe  
      my $sth=$dbh->prepare('SELECT * FROM prospects');  
      $sth->execute();  
      while(my @row = $sth->fetchrow_array){  
                                            print join('; ',@row)."\n";  
                                            }  
      $sth->finish;  
        
      my $row;  
        
      $sth = $dbh->prepare("SELECT * FROM prospects WHERE name LIKE 'G%'");  
      $sth->execute();  
      while (my $row = $sth->fetchrow_hashref){  
                                              print("name = $row->{Name}  contact = $row->{Contact}"."\n");  
                                              }  
      $sth->finish();  
        
      $dbh->disconnect();  
      
      

      CSV-Inhalt (Dateiname: prospects.csv):

      -----------------------------------------------------------------------------
      "Name","Address","Floors","Donated last year","Contact"
      "Charlotte French Cakes","1179 Glenhuntly Rd","1","Y","John"
      "Glenhuntly Pharmacy","1181 Glenhuntly Rd","1","Y","Paul"
      "Dick Wicks Magnetic Pain Relief","1183-1185 Glenhuntly Rd","1","Y","George"
      "Gilmour's Shoes","1187 Glenhuntly Rd","1","Y","Ringo"
      -----------------------------------------------------------------------------

      Ich versuche mit diesem Übungscode eine DBD::CSV anzusteuern. Das gelingt nur teilweise. Die Ausgabe im Terminal sieht so aus:

      -----------------------------------------------------------------------------
      Name; Address; Floors; Donated last year; Contact
      Charlotte French Cakes; 1179 Glenhuntly Rd; 1; Y; John
      Glenhuntly Pharmacy; 1181 Glenhuntly Rd; 1; Y; Paul
      Dick Wicks Magnetic Pain Relief; 1183-1185 Glenhuntly Rd; 1; Y; George
      Gilmour's Shoes; 1187 Glenhuntly Rd; 1; Y; Ringo
      Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 52.
      Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 52.
      name =   contact =
      Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 52.
      Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 52.
      name =   contact =
      -----------------------------------------------------------------------------

      Irgendwo ist noch ein kleiner Fehler, den ich nicht finden kann.

      Gruss HP-User

  2. hi,

    Wie kommen die Anführungszeichen bzw die einzelnen Apostrophstriche hin?

    Von außen nach innen und paarweise ;)

      
    print("name = $row->{Name}  'contact = $row->{Contact}' \n";  
    
    

    Tipp: Verwende q() oder qq() für einfach bzw. doppelt quoten, das ist oftmals übersichtlicher.

    Hotti

    1. hi,

      Wie kommen die Anführungszeichen bzw die einzelnen Apostrophstriche hin?

      Von außen nach innen und paarweise ;)

      print("name = $row->{Name}  'contact = $row->{Contact}' \n";

        
      Die Klammern () auch paarweise, da oben fehlt eine ;)  
        
      Arrow-Operator:  
      `print "$row->{Name}\n";`{:.language-perl}  
        
      Hier wird dereferenziert, es entsteht ein Scalar, das wird innerhalb der doppelten Anführungszeichen interpoliert. Syntax ok.  
        
      Wenn Du eine Methode aufrufst:  
      `$obj->method();`{:.language-perl}  
        
      und das Ergebnis derer gleich ausgeben möchtest, geht das so:  
        
      ~~~perl
        
      print "@{[$obj->check_email('r.rr@example.com')]}\n";  
      
      

      ohne dass die Rückgabewerte (print erwartet eine Liste) auf einem explizit angegebenen Array aufgefangen werden müssen.

      Ein print "@liste"; gibt die Einzelelemente schön sauber durch Leerzeichen getrennt in einer Zeile aus.

      Hotti

    2. Hi hotto

      Tipp: Verwende q() oder qq() für einfach bzw. doppelt quoten, das ist oftmals übersichtlicher.

      Geht auch nicht :-(

      Hier das Übungsprogramm. Im ersten Ausgabeteil wird die komplette CSV ausgegeben. Im Zweiten Teil sollte nur Felder mit "G" ausgegebenwerden. Das ganze sollte eine Übung zum ansprechen von CSV-Dateien als DB sein.m Sollte - weil es klappt einfach nicht. Aktueller Perl Code:

        
      #!/usr/bin/perl  
        
      # sollte in keinem Script fehlen  
      use strict;  
      use warnings;  
        
      # DBI Modul Laden  
      use DBI;  
        
      # Verzeichnis mit dem Script finden.  
      # "." muss nicht immer das Verzeichnis mit dem Script sein  
      use FindBin '$Bin';  
        
      # Sollte man machen.  
      # es hilft die Dateinamen  
      # von den Tabellennamen zu trennen.  
      my %zuordnung=(  
                    prospects => {  
                    file => 'prospects.csv',  
                    col_names   => ['Name', 'Address', 'Floors', 'Donated last year', 'Contact'],  
                    },  
                    );  
        
      # Verbindung aufbauen  
      my $dbh = DBI->connect("DBI:CSV:", undef, undef, {  
                                                        # Zeilenseparator  
                                                        csv_eol => "\x0A",  
                                                        # Spaltenseparator:  
                                                        csv_sep_char => ",",  
                                                        # Verzeichnis mit den Dateien  
                                                        f_dir => $Bin,  
                                                        # Zuordnung Dateiname -> Tabelle  
                                                        csv_tables => \%zuordnung,  
                                                        # bei Fehlern immer sterben:  
                                                        RaiseError => 1,  
                                                        }  
                            ) or die($DBI::errstr);  
        
      # Testausgabe Nr.1: ganze CSV  
      my $sth=$dbh->prepare('SELECT * FROM prospects');  
      $sth->execute();  
      while(my @row = $sth->fetchrow_array){  
                                            print join('; ',@row)."\n";  
                                            }  
      $sth->finish;  
        
      #Textausgabe Nr.2: sortierte CSV  
      $sth = $dbh->prepare("SELECT * FROM prospects WHERE Name LIKE 'G%'");  
      $sth->execute();  
      while (my $row = $sth->fetchrow_hashref){  
                                              print qq(name = $row->{Name}  contact = $row->{Contact})."\n";  
                                              }  
      $sth->finish();  
        
      $dbh->disconnect();  
      
      

      Diese "hash"-Geschichte macht mich echt noch fertig.
      Hier die Ausgabe im Terminal inkl. Fehler:

      -----------------------------------------------------------------------
      Name; Address; Floors; Donated last year; Contact
      Charlotte French Cakes; 1179 Glenhuntly Rd; 1; Y; John
      Glenhuntly Pharmacy; 1181 Glenhuntly Rd; 1; Y; Paul
      Dick Wicks Magnetic Pain Relief; 1183-1185 Glenhuntly Rd; 1; Y; George
      Gilmour's Shoes; 1187 Glenhuntly Rd; 1; Y; Ringo
      Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 51.
      Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 51.
      name =   contact =
      Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 51.
      Use of uninitialized value in concatenation (.) or string at ./DB-Test.pl line 51.
      name =   contact =
      -----------------------------------------------------------------------

      Ziel:
      Es soll in der Namespalte alle datensätze angezeigt werden, die ein "G" enthalten oder mit "G" beginnen - so genau hab ich das Beispiel noch nicht verstanden. Aber es sollte doch zumindest ohne Fehlermeldung arbeiten.

      Also: Wer einen Anhaltspunkt sieht, was hier falsch läuft, darf es mir gerne mitteilen. Ich bin nach unzähligen Versuchen mit meinem Latein am Ende.

      Gruss HP-User

      P.S.
      (Ich hol mir jetzt erst einmal einen Caffe! Den hab ich mir verdient und der beruhigt die Nerven :-)

      1. Hi lieber Mitstreiter ;)

        Tipp: Verwende q() oder qq() für einfach bzw. doppelt quoten, das ist oftmals übersichtlicher.

        Geht auch nicht :-(

        Abgelehnt! Lerne Quoten ;)

        Hier das Übungsprogramm.

        Nein, Dein Komplettprogramm werde ich nicht überarbeiten. Du kannst das!
        Schrit für Schritt und das Hauruck erst am Schluss ;)

        Noch ein paar Grundlagen: Arrays schön und gut, aber Du musst oft nachschauen, auf welchem Index [0], [1] ... welcher Wert zu finden ist. Vorschlag: Arbeite mit einem Hash und nenne die Felder beim Namen.

          
        my @header = qw(Name Vorname Ort PLZ);                # Beispiel  
        my @row_array = ("Rost", "Rolf", "Oppenheim", 55276); # CSV Zeile  
        my %row_hash = ();                                    # declare  
        # Hash-Slice  
        @row_hash{@header} = @row_array;         # den Feldern Werte zuweisen  
          
        print Dumper \%row_hash;  
          
        $VAR1 = {  
                  'PLZ' => 55276,  
                  'Ort' => 'Oppenheim',  
                  'Vorname' => 'Rolf',  
                  'Name' => 'Rost'  
                };  
        # Eizelfeld ansprechen  
        print $row_hash{Name};  
          
        # Referenz  
        my $ref = \%row_hash;  
        print $ref->{Name};  
          
        # bischen quoten  
        print qq(Name: $ref->{Name})."\n";  
          
        # einfacher alles zusammen  
        print "Name: $ref->{Name\\n";  
          
        # quoten und verketten like PHP  
        $addr = array(  
        	"Name" => "Rost",  
        );  
        print("Name: ".$addr['Name']."\n");  
          
        
        

        Hotti

        1. Hi hotti

          Alles klar *g*
          Gut, ich habe das ganze Konstrukt entfernt. Alles zurück auf Null!
          Ich weiss zwar noch nicht, wie mir dein Array und Hash lergang bei meinem Datenbankprojekt helfen kann, aber Fakt ist, ich habe über diese beiden Dinge wenig Ahnung! Also los...

          So sieht übrigens "dein" Lernprog für Perl bis jetzt aus (was auch nicht funktioniert):

            
          #!/usr/bin/perl  
            
          use strict;  
          use warnings;  
          use DBI;  
            
          my @header = qw(Name Vorname Ort PLZ);                # Beispiel  
          my @row_array = ("Rost", "Rolf", "Oppenheim", 55276); # CSV Zeile  
          my %row_hash = ();                                    # declare  
          # Hash-Slice  
          @row_hash{@header} = @row_array;         # den Feldern Werte zuweisen  
            
          print Dumper \%row_hash;  
            
          my $VAR1 = {  
                        'PLZ' => 55276,  
                        'Ort' => 'Oppenheim',  
                    'Vorname' => 'Rolf',  
                       'Name' => 'Rost'  
                     };  
          # Eizelfeld ansprechen  
          print $row_hash{Name};  
            
          # Referenz  
          my $ref = \%row_hash;  
          print $ref->{Name};  
            
          # bischen quoten  
          print qq(Name: $ref->{Name})."\n";  
            
          # einfacher alles zusammen  
          print "Name: $ref->{Name}\n";  
            
          # quoten und verketten like PHP  
          my $addr = array("Name" => "Rost",);  
          print("Name: ".$addr['Name']."\n");  
          exit();  
          
          

          Bevor wir das auseinanderpflücken, wär es nett, wenn du mir bei der Fehlersuche deines Programms helfen könntest. Ein Paar "my's" hab ich schon hinzugefügt/korrigiert.

          Die Fehlermeldung der Terminalausgabe lautet so:

          ---------------------------------------------------------------------
          Global symbol "@addr" requires explicit package name at ./DB-Test.pl line 36.
          Execution of ./DB-Test.pl aborted due to compilation errors.

          ---------------------------------------------------------------------

          Der Witz dieser Fehlermeldung: Es gibt gar kein Array "@addr". Manmanman - Computers wat 'n Stress!

          Grüsse HP-User

          1. Hi Hotti

            Das ursprüngliche Programm funktioniert jetzt. War ein Groß-Kleinschreibeproblem:

              
            print Dumper (my $row = $sth->fetchrow_hashref);  
              
            while (my $row = $sth->fetchrow_hashref){  
                                                    print qq(Name = $row->{name}  Contact = $row->{contact})."\n";  
                                                    }  
            
            

            Also die Klammerwerte {Name} und {Contact} waren klein zu schreiben.
            Das interessante daran: Weder im Hauptprogramm zeile 19, noch in der CSV-Datei sind diese Werte kleingeschrieben. Das bedeutet, dass wohn DBI-DBD-CSV die Werte automatisch in kleinen Buchstaben ausliefert?

            Na ja, da muss ich noch genauer recherchieren, woher dieser Hash Inhalt herkommt.

            Gruss HP

            1. hi,

              Also die Klammerwerte {Name} und {Contact} waren klein zu schreiben.

              Da gibt es für den connect() ein Attribut DBD::CSV

              FetchHashKeyName => "NAME_lc",

              Das interessante daran: Weder im Hauptprogramm zeile 19, noch in der CSV-Datei sind diese Werte kleingeschrieben. Das bedeutet, dass wohn DBI-DBD-CSV die Werte automatisch in kleinen Buchstaben ausliefert?

              Doku lesen (Mist, macht Arbeit *G*).

              (driver flags, wird wohl der Default sein ;)

              Na ja, da muss ich noch genauer recherchieren, woher dieser Hash Inhalt herkommt.

              Stichwort: col_names

              Und auch:
              skip_first_row

              By default DBD::CSV assumes that column names are stored in the first row of the CSV file ...

              Aber schön, dass Du hier mit Perl unterwegs bist!

              Hotti