Alexander Foken: Array-Referenzen: Ich seh' den Wald vor lauter Bäumen nicht !

Moin Moin !

Ein (ganz kleines) Stückchen aus meinem aktuellen Projekt, über das ich vor einigen Tagen gestolpert bin:

$table->SetRow([ ('STRING(255)') x scalar @columns ],@columns [ ($importerfmt) x scalar @columns ]);

Der Funktionsaufruf oben erzeugt ein "out of memory", der unten nicht. Das ist aber nicht das Problem.

$table->SetRow([ ('STRING(255)') x scalar @columns ],@columns,[ ($importerfmt) x scalar @columns ]);

Fehler kommen vor, was soll's. Aber:

Im oberen Funktionsaufruf fehlt die hinter @columns das Komma. Eigentlich hätte der Compiler das anmeckern müssen. Hat er aber nicht. Ich hab noch nicht ganz verstanden, was der Compiler da reininterpretiert hat. Das Verhalten ist aber nachvollziehbar. Ich hab mal ein wenig rumprobiert, wann zwei Array-Referenzen ohne Operator keine Fehlermeldung liefern:

perl -e "print(1,2,3)"

123

perl -e "print([1,2,3][4,5,6])"

syntax error at -e line 1, near "]["

Execution of -e aborted due to compilation errors.

perl -e "print( [1,2,3] [4,5,6] )"

syntax error at -e line 1, near "] ["

Execution of -e aborted due to compilation errors.

perl -e "my @a=(1,2,3); print( @a [4,5,6] )"

SCALAR(0x1a7f180)SCALAR(0x1a7f198)SCALAR(0x1a7f1a4)

perl -e "my @a=(1,2,3); print( @a [4,5,6,7] )"

SCALAR(0x1a7f180)SCALAR(0x1a7f198)SCALAR(0x1a7f1a4)SCALAR(0x1a7517c)

Wenn die erste Array-Referenz also eine Variable, nicht ein anonymes Array ist, gibt es keinen Fehler. Aber was ?

perl -MData::Dumper -e "my @a=(1,2,3); print Dumper( @a [4,5,6,7] )"

$VAR1 = \undef;
$VAR2 = \undef;
$VAR3 = \undef;
$VAR4 = \undef;

Was passiert hier ? Referenzen auf undef ?

Das ist sicher irgendein normalerweise ganz sinnvoller Mechanismus, der an dieser Stelle nur noch Unsinn macht. Ich komm' nur im Moment nicht drauf, wozu das gut sein sollte.

Kann mir bitte mal jemand ein paar Bäume wegsägen, damit ich wieder den Wald sehen kann ?

Alexander

PS: Ich vergaß:

Microsoft Windows 2000 [Version 5.00.2195]
(C) Copyright 1985-2000 Microsoft Corp.

perl -V

Summary of my perl5 (revision 5 version 6 subversion 0) configuration:
  Platform:
    osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread
    uname=''
    config_args='undef'
    hint=recommended, useposix=true, d_sigaction=undef
    usethreads=undef use5005threads=undef useithreads=define usemultiplicity=def
ine
    useperlio=undef d_sfio=undef uselargefiles=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef usesocks=undef
  Compiler:
    cc='cl', optimize='-O1 -MD -DNDEBUG', gccversion=
    cppflags='-DWIN32'
    ccflags ='-O1 -MD -DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT
 -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DPERL_MSVCRT_READFIX'
    stdchar='char', d_stdstdio=define, usevfork=false
    intsize=4, longsize=4, ptrsize=4, doublesize=8
    d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize
=4
    alignbytes=8, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='link', ldflags ='-nologo -nodefaultlib -release  -libpath:"C:\Perl\lib\C
ORE"  -machine:x86'
    libpth=/lib /usr/lib /usr/local/lib "C:\Perl\lib\CORE"
    libs=  oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib  comdlg32
.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib  netapi32.lib uuid.lib wsoc
k32.lib mpr.lib winmm.lib  version.lib odbc32.lib odbccp32.lib msvcrt.lib
    libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl56.lib
  Dynamic Linking:
    dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -release  -libpath:"C:
\Perl\lib\CORE"  -machine:x86'

Characteristics of this binary (from libperl):
  Compile-time options: MULTIPLICITY USE_ITHREADS PERL_IMPLICIT_CONTEXT PERL_IMP
LICIT_SYS
  Locally applied patches:
        ActivePerl Build 620
  Built under MSWin32
  Compiled at Oct 31 2000 18:31:05
  @INC:
    C:/Perl/lib
    C:/Perl/site/lib
    .

PPS:
Ja, Windows 2000. Ich bin jung und brauche das Geld. *Schnief* ;-)

  1. Hallo,

    $table->SetRow([ ('STRING(255)') x scalar @columns ],@columns [ ($importerfmt) x scalar @columns ]);

    Der Funktionsaufruf oben erzeugt ein "out of memory", der unten nicht. Das ist aber nicht das Problem.

    $table->SetRow([ ('STRING(255)') x scalar @columns ],@columns,[ ($importerfmt) x scalar @columns ]);

    Ist ja auch etwas voellig anderes :)

    Im oberen Funktionsaufruf fehlt die hinter @columns das Komma. Eigentlich
    hätte der Compiler das anmeckern müssen.

    Warum?

    Hat er aber nicht. Ich hab noch nicht ganz verstanden, was der Compiler da
    reininterpretiert hat.

    Fuer den Interpreter(!) ist

    @columns [($importerfmt) x scalar @columns])

    dasselbe wie

    (@columns[($importerfmt) x scalar @columns])

    Will heissen, du erstellst damit eine Liste von Referenzen auf Skalare.

    perl -e "print(1,2,3)"

    123

    Eine normale Liste.

    perl -e "print([1,2,3][4,5,6])"

    syntax error at -e line 1, near "]["

    Klar. Man kann eine Referenz nicht einfach so splicen.

    Execution of -e aborted due to compilation errors.

    perl -e "print( [1,2,3] [4,5,6] )"

    syntax error at -e line 1, near "] ["

    Dito.

    Execution of -e aborted due to compilation errors.

    perl -e "my @a=(1,2,3); print( @a [4,5,6] )"

    SCALAR(0x1a7f180)SCALAR(0x1a7f198)SCALAR(0x1a7f1a4)

    ist dasselbe wie:

    print $a[4],$a[5],$a[6];

    perl -e "my @a=(1,2,3); print( @a [4,5,6,7] )"
    SCALAR(0x1a7f180)SCALAR(0x1a7f198)SCALAR(0x1a7f1a4)SCALAR(0x1a7517c)

    Siehe oben.

    Gruesse,
     CK

    1. Hallo,

      Moin Moin !

      $table->SetRow([ ('STRING(255)') x scalar @columns ],@columns [ ($importerfmt) x scalar @columns ]);

      Der Funktionsaufruf oben erzeugt ein "out of memory", der unten nicht. Das ist aber nicht das Problem.

      $table->SetRow([ ('STRING(255)') x scalar @columns ],@columns,[ ($importerfmt) x scalar @columns ]);

      Ist ja auch etwas voellig anderes :)

      Das habe ich gemerkt, aber den Grund nicht gesehen.

      Im oberen Funktionsaufruf fehlt die hinter @columns das Komma. Eigentlich
      hätte der Compiler das anmeckern müssen.

      Warum?

      Weil, weil, weil ... - Weil ich das so haben will. ;-)

      Nein, weil mir die Erklärung nicht in den Sinn kam, hab ich in der Zeile einfach einen Syntax-Fehler gelesen, den der Compiler nicht angemeckert hat.

      Fuer den Interpreter(!) ist

      Perl wird in Pseudocode compiliert, der dann interpretiert wird, AFAIK. Egal. Einigen wir uns für heute auf "PERL.EXE" ;-)

      @columns [($importerfmt) x scalar @columns])

      dasselbe wie

      (@columns[($importerfmt) x scalar @columns])

      Will heissen, du erstellst damit eine Liste von Referenzen auf Skalare.

      Das ist die Erklärung, vielen Dank!

      perl -e "my @a=(1,2,3); print( @a [4,5,6] )"

      SCALAR(0x1a7f180)SCALAR(0x1a7f198)SCALAR(0x1a7f1a4)

      ist dasselbe wie:

      print $a[4],$a[5],$a[6];

      ... die alle gerade nicht definiert sind. Mit [1,2,3] wäre mir wahrscheinlich ein Licht aufgegangen.

      Danke nochmal!

      Alexander

      1. Morsche,

        Fuer den Interpreter(!) ist

        Perl wird in Pseudocode compiliert, der dann interpretiert wird, AFAIK.

        Nope. Das ist Perl6 mit Parrot. Perl5 wandelt in Syntax-Baeume um. Tatsache
        ist, dass Perl interpretiert und nicht compiliert wird.

        Gruesse,
         CK