Array-Referenzen: Ich seh' den Wald vor lauter Bäumen nicht !
Alexander Foken
- perl
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* ;-)
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
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
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