Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re^4: What does my @x= (undef)x7; do?

by betterworld (Curate)
on Nov 09, 2015 at 17:53 UTC ( #1147267=note: print w/replies, xml ) Need Help??


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

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.

Replies are listed 'Best First'.
Re^5: What does my @x= (undef)x7; do?
by AnomalousMonk (Archbishop) on Nov 09, 2015 at 18:34 UTC

    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:  <%-{-{-{-<

Re^5: What does my @x= (undef)x7; do?
by BrowserUk (Patriarch) on Nov 10, 2015 at 04:55 UTC

    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.
      You do realise that you aren't passing the array into modify()? You're passing a list. And that list is being aliased.

      Yes I do :) It's a list of aliases, just like in the subroutine GetVolumeInformation from the original post.

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

      I think this is related to some optimization. Some people like to use $#array = ... because it is faster than explicitly filling the array. However this optimization comes with a cost.

      Assigning to the length does not put any SVs into the new elements, and this is why you cannot create references or aliases to them. I thought there was something about this in the documentation, but I cannot find it any more (only a related section in perlguts)

        I think this is related to some optimization. Some people like to use $#array = ... because it is faster than explicitly filling the array.

        Oh those naughty "some people"; using a defined language feature in the way it was designed.


        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.

      I would be very interested in any comments you might have on the, to me, very puzzling behavior seen when iterating over the aliased  @_ argument list with arrays  @b and  @c in the  modify() function in the reply above. I have only been able to confirm this behavior in the older Perl versions noted therein.


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

        I assume the main point of confusion is the last case where only one of the elements get modified?


        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.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1147267]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2022-12-03 09:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?