in reply to Re: What does my @x= (undef)x7; do?
in thread What does my @x= (undef)x7; do?

Yes, it should work; but, strangely, it doesn’t:

#! perl use strict; use warnings; use Data::Dump; use Win32API::File qw(getLogicalDrives GetVolumeInformation); my @drives = getLogicalDrives(); for my $d (@drives) { # my @x = (undef) x 7; my @x; $#x = 6; # dd \@x; GetVolumeInformation($d, @x); print "$d $x[0] ($x[5])\n"; }

Output:

1:16 >perl 1442_SoPW.pl Modification of a read-only value attempted at C:/Perl/Strawberry/stra +wberry-perl-5.22.0.1-64bit-PDL/perl/lib/Win32API/File.pm line 269. 1:16 >

But with the line dd \@x; uncommented, it does work:

1:16 >perl 1442_SoPW.pl [undef, undef, undef, undef, undef, undef, undef] C:\ (NTFS) [undef, undef, undef, undef, undef, undef, undef] D:\ () [undef, undef, undef, undef, undef, undef, undef] E:\ () 1:16 >

What’s going on?

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Replies are listed 'Best First'.
Re^3: What does my @x= (undef)x7; do?
by BrowserUk (Patriarch) on Nov 09, 2015 at 15:32 UTC
    What’s going on?

    The explicit method populates the array with 7 physical pointers to undef:

    [0] Perl> @x = (undef)x7;; [0] Perl> use Devel::Peek;; [No such file or directory] Perl> Dump \@x;; SV = RV(0x3c735d0) at 0x3c735c0 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x3c6ac88 SV = PVAV(0x3cfafd8) at 0x3c6ac88 REFCNT = 2 FLAGS = (RMG) MAGIC = 0x3cee198 MG_VIRTUAL = &PL_vtbl_arylen_p MG_TYPE = PERL_MAGIC_arylen_p(@) MG_FLAGS = 0x02 REFCOUNTED MG_OBJ = 0x3c6a410 SV = PVMG(0x3b1a078) at 0x3c6a410 REFCNT = 1 FLAGS = (GMG,SMG,pIOK) IV = 6 NV = 0 PV = 0 MAGIC = 0x3ceea08 MG_VIRTUAL = &PL_vtbl_arylen MG_TYPE = PERL_MAGIC_arylen(#) MG_OBJ = 0x3c6ac88 ARRAY = 0x3cf1398 FILL = 6 MAX = 7 ARYLEN = 0x3c6a410 FLAGS = (REAL) Elt No. 0 SV = NULL(0x0) at 0x3cb4b98 REFCNT = 1 FLAGS = () Elt No. 1 SV = NULL(0x0) at 0x3c73578 REFCNT = 1 FLAGS = () Elt No. 2 SV = NULL(0x0) at 0x3cb49b8 REFCNT = 1 FLAGS = () Elt No. 3 SV = NULL(0x0) at 0x3cb4af0 REFCNT = 1 FLAGS = ()

    Whereas, when you pre-extend the array, no physical pointer are populated; the undef's are implied by the absence of pointers:

    [0] Perl> undef @x;; [0] Perl> $#x = 6;; [0] Perl> Dump \@x;; SV = RV(0x3c735d0) at 0x3c735c0 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x3c6ac88 SV = PVAV(0x3cfafd8) at 0x3c6ac88 REFCNT = 2 FLAGS = (RMG) MAGIC = 0x3cee198 MG_VIRTUAL = &PL_vtbl_arylen_p MG_TYPE = PERL_MAGIC_arylen_p(@) MG_FLAGS = 0x02 REFCOUNTED MG_OBJ = 0x3c6a410 SV = PVMG(0x3b1a078) at 0x3c6a410 REFCNT = 1 FLAGS = (GMG,SMG,pIOK) IV = 6 NV = 0 PV = 0 MAGIC = 0x3ceea08 MG_VIRTUAL = &PL_vtbl_arylen MG_TYPE = PERL_MAGIC_arylen(#) MG_OBJ = 0x3c6ac88 ARRAY = 0x3cf1398 FILL = 6 MAX = 6 ARYLEN = 0x3c6a410 FLAGS = (REAL) Elt No. 0 Elt No. 1 Elt No. 2 Elt No. 3

    Perl code would treat the two the as the same, but user-written XS code makes assumptions.

    Thanks for checking it.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Perl code would treat the two the as the same, but user-written XS code makes assumptions.

      When I read this, I felt an urge to find Perl code that behaves differently for these arrays :)

      Turns out that what this API function is doing would require explicit undefs even if the function was written in Perl. This is a subroutine that modifies its input parameters. In Perl you might write it like this:

      use Data::Dumper; my @a; @a = (undef) x 5; my @b; $#b = 4; sub modify { $_ = 5 for @_; } modify(@a); print Dumper \@a; modify(@b); print Dumper \@b;

      Here the subroutine "modify" behaves similar to GetVolumeInformation as it modifies the scalars in the array passed to it.

      So the arrays @a and @b should be identical. However, modify() will replace @a with five times 5, but it cannot write to @b:

      $VAR1 = [ 5, 5, 5, 5, 5 ]; Modification of a read-only value attempted at script.pl line 12.

      Update: Since this seems to depend on the version: I am using Perl 5.20.2 on Debian.

        I don't see your pure-Perl "Modification of a read-only value..." result on ActiveState 5.8.9 and Strawberry 5.14.4.1 (Update: likewise Strawberries 5.10.1.5 and 5.12.3.0), but there's something else I don't understand:

        c:\@Work\Perl\monks>perl -wMstrict -MData::Dumper -le "sub modify { $_ = 5 for @_; } ;; my @a; @a = (undef) x 5; ;; modify(@a); print Dumper \@a; ;; my @b; $#b = 4; ;; modify(@b); print Dumper \@b; ;; my @c; $#c = 4; $c[ $#c ] = undef; ;; modify(@c); print Dumper \@c; " $VAR1 = [ 5, 5, 5, 5, 5 ]; $VAR1 = [ undef, undef, undef, undef, undef ]; $VAR1 = [ undef, undef, undef, undef, 5 ];
        Arrays @b and @c are still unwriteable (or at least unwritten, at least in part), but in a different way.   ?!?

        Update: Taking the  @_ argument list out of the equation, I get expected results (thank Larry!) for the problematic cases above (for all Perl versions listed in the first paragraph):

        c:\@Work\Perl\monks>perl -wMstrict -MData::Dumper -le "my @b; $#b = 4; ;; $_ = 5 for @b; print Dumper \@b; ;; my @c; $#c = 4; $c[ $#c ] = undef; ;; $_ = 6 for @c; print Dumper \@c; " $VAR1 = [ 5, 5, 5, 5, 5 ]; $VAR1 = [ 6, 6, 6, 6, 6 ];


        Give a man a fish:  <%-{-{-{-<

        You do realise that you aren't passing the array into modify()? You're passing a list. And that list is being aliased.

        And prior to the mostly pointless, blanket constanisation of the Perl sources, the (incorrect) attribution of a null C pointer to a scalar would not have been spuriously attributed to a "read-only value".

        Two mistakes collide here:

        1. The lazy definition of an api that takes a list of pre-existing and defined variables as input in order to provide output.
        2. The retroactive application of const'ing at the C-level with callous disregard to the affects at the Perl level.

        Upshot: p5p have buggered Perl5 in their attempts to 'be correct'.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
        In the absence of evidence, opinion is indistinguishable from prejudice.