in reply to Re: Internals question.
in thread Internals question.

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.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^3: Internals question.
by diotalevi (Canon) on Jul 23, 2007 at 17:57 UTC

    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.

        It'd be easier for you to write a little bit of XS and allocate your SV, replace SvANY(your_sv) with AvARRAY(your_av). Now you've got to prevent perl from wanting to ever deallocate either object before you can undo your muckery. The array at AvARRAY(your_av) could now get freed twice and the original buffer at SvANY(your_sv) might never be freed. B is just a little bit of sugar over XS so you'd really be better off just checking that out. Visit perlapi and the various *v.h files in your distribution.

        ⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊

        Perl assumes that it can call free() or realloc() on PVXs with impunity. This prevents many useful "tricks".

        - tye        

      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
Re^3: Internals question.
by Anonymous Monk on Jul 23, 2007 at 16:39 UTC
    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.