in reply to Internals question.

When I tried that, I got the oddball in the 8th position, not the second. Expanding it to 20 or 30, it just seems that the array memory is being recycled, probably at least twice, before you get it.

A word spoken in Mind will reach its own level, in the objective world, by its own weight

Replies are listed 'Best First'.
Re^2: Internals question.
by BrowserUk (Patriarch) on Jul 23, 2007 at 14:57 UTC

    Yes. I think you are right. I also get different results depending upon what has gone on before, but always the same results if the same things have previously happened. So, no matter how many times I run this:

    c:\test>perl -wle"$#a = 10; print \$_ for @a" SCALAR(0x225138) SCALAR(0x225120) SCALAR(0x225144) SCALAR(0x225168) SCALAR(0x1824378) SCALAR(0x224f4c) SCALAR(0x2250f0) SCALAR(0x18243cc) SCALAR(0x18243d8) SCALAR(0x18243e4) SCALAR(0x18243f0)

    I always get those same addresses. The thing I fond confusing is teh way the low and high areans get mixed up.

    For example. When I run these two, notice how the first 7 addresses are the same in both, but then the last 3 vary.

    c:\test>perl -wle"@b = 1.. 10; $#a = 10; print \$_ for @a" Name "main::b" used only once: possible typo at -e line 1. SCALAR(0x225138) SCALAR(0x225120) SCALAR(0x225144) SCALAR(0x225168) SCALAR(0x18243b0) SCALAR(0x1824428) SCALAR(0x1824434) SCALAR(0x1824440 +) SCALAR(0x182beac) SCALAR(0x182beb8) SCALAR(0x182bec4) c:\test>perl -wle"@b = 1.. 100; $#a = 10; print \$_ for @a" Name "main::b" used only once: possible typo at -e line 1. SCALAR(0x225138) SCALAR(0x225120) SCALAR(0x225144) SCALAR(0x225168) SCALAR(0x18243b0) SCALAR(0x1824428) SCALAR(0x1824434) SCALAR(0x1824440 +) SCALAR(0x182bd80) SCALAR(0x182bd8c) SCALAR(0x182bd98)

    And if you go on to:

    c:\test>perl -wle"@b = 1.. 1000; $#a = 10; print \$_ for @a" Name "main::b" used only once: possible typo at -e line 1. SCALAR(0x225138) SCALAR(0x225120) SCALAR(0x225144) SCALAR(0x225168) SCALAR(0x18243b0) SCALAR(0x1824428) SCALAR(0x1824434) SCALAR(0x1824440 +) SCALAR(0x2267c8) SCALAR(0x2267d4) SCALAR(0x2267e0)

    It suddenly starts reusing earlier addresses.

    It came up because I was trying to code something that would rely upon the relative address of the items in an array being in ascending order--but that's a guarentee that Perl simply cannot make.

    What I really need access to is the (C) array of pointers pointed at by the ARRAY field of the XPVAV, but I would have to drop into XS to get that. Still that might be the only way to do what I am trying to do.

    That said, inspiration hit me whilst typing this and I stuck the code is a begin block:

    c:\test>perl -wle"BEGIN{ $#a = 10; print \$_ for @a }" SCALAR(0x182c120) SCALAR(0x182c114) SCALAR(0x182c12c) SCALAR(0x182c138 +) SCALAR(0x182c144) SCALAR(0x182c150) SCALAR(0x182c15c) SCALAR(0x182c168 +) SCALAR(0x182c174) SCALAR(0x182c180) SCALAR(0x182c18c)

    And that seems to produce the effect I am after regardles of what else goes on, provided I ensure that my BEGIN block is run first. Or maybe I should just bite the bullet and code it in Inline::C.


    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".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      You can use some perverted B for this. Maybe. This takes an AV, casts it to PV, makes it a real scalar, then fetches the value of the svu_pv pointer which I guess is the same as the svu_array pointer.

      my $addr = pack 'p', bless( svref_2object( \ @ary ), 'B::PV' )->object_2svref;

      ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

        Oh. That's perfect. I had to do in in two steps to avoid a 'Attempt to pack pointer to temporary value...' message, but that is much nicer than what I was attempting to do.

        Just one further question. I could probably work it for myself, but since you seem to have specialised in all things B, how can I take that sv_ref and set it into a perl scalar?

        Ie. I would like to have a standard perl scalar with the PVX pointing at the same space as an AVs ARRAY field. Actually, It would be better if the SV(PVX) shared the same value as the AV(ALLOC), but that's probably asking too much.

        Can you short-circuit the learning curve for me?


        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".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        You can use some perverted B for this. Maybe. This takes an AV, casts it to PV...

        Thanks; now I know what PV really stand for. ;-)

        A word spoken in Mind will reach its own level, in the objective world, by its own weight
      That said, inspiration hit me whilst typing this and I stuck the code is a begin block

      ...and something else may hit you six months from now when the underlying implementation changes for any number of reasons.
      if you want C code, best to code in C.

        But 6 days from now, the intellectual spark that motivated me to explore the idea that brought this up will either be satisfied or discarded. Unless I use C, in which case, I'll still be trying to code it 6 months from now.


        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".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re^2: Internals question.
by ForgotPasswordAgain (Vicar) on Jul 23, 2007 at 12:24 UTC

    Hmm, I didn't get anything weird during at least 10000 iterations:

    # all like SCALAR(0x81nnnnn) $ perl -le'$#a=10000;print \$_ for @a' |fgrep -v x81 $

    But I'm on Ubuntu, not Windows, so maybe it's different.