develooper Front page | perl.perl5.porters | Postings from March 2023

Re: refaliasing disrespects readonlyness of array or hash

Thread Previous | Thread Next
From:
Zefram via perl5-porters
Date:
March 20, 2023 20:33
Subject:
Re: refaliasing disrespects readonlyness of array or hash
Message ID:
ZBjDB5n40lSQH0yZ@fysh.org
demerphq wrote:
>took a reference to the literal 555.  Restricted hashes prevent deleting a
>value that is marked as readonly. You just happened to use a test case that
>stored a readonly value in the hash in the first place.

Ah, I stand corrected, thank you.  There *is* some relevance of the
restricted hash semantics, and, as you've shown, those semantics are such
that it is correct for them to not prevent the refaliasing operation in
my original test case.  I certainly need to look again at the restricted
hash semantics and related subjects.

>Why would marking an anonymous scalar reference read-only prove anything?

There are multiple things going on with this question.

I think you've misunderstood the calls to Internals::SetReadOnly(),
presumably because you're thinking in terms of Internals::SvREADONLY().
They have different argument conventions.  Internals::SvREADONLY() (from
the core) has a "\[$%@];$" prototype, meaning that (for bareword calls)
the first argument gets implicitly enreferenced.  Internals::SetReadOnly()
(from CPAN) has no prototype, so no implicit enreferencement.  Both
require the actual first argument to be a reference to the object
to operate on.  So "Internals::SetReadOnly(\$x)" is equivalent to
"Internals::SvREADONLY($x, 1)", not to "Internals::SvREADONLY(\$x, 1)"
(which doesn't compile).  So the "SetReadOnly(\$a{bb});" invocation that
I proposed isn't making a completely anonymous scalar (the RV referencing
$a{bb}) readonly, it's making $a{bb} readonly.

My intent was that making the hash element scalar readonly would clear
up a confusion that I thought that you had fallen into.  I was mistaken;
you didn't actually have the misunderstanding that I thought you did.
So making that scalar readonly doesn't have the relevance that I thought
it did.

But actually it *does* prove something relevant.  Making the hash
element scalar readonly when the hash itself is restricted invokes
exactly that bit of the restricted hash semantics that you explained my
test case accidentally invoked.  With the hash element scalar readonly,
deletion via "delete" is prevented, so now ostensibly Perl doesn't allow
that scalar to be replaced.  But the refaliasing operation still works,
so in *this* case the refaliasing breaks the hash's restriction:

$ perl -Mexperimental=refaliasing -lwe '%a = (aa=>11,bb=>22,cc=>33); Internals::SvREADONLY(%a, 1); Internals::SvREADONLY($a{bb}, 1); delete $a{bb}'
Attempt to delete readonly key 'bb' from a restricted hash at -e line 1.
$ perl -Mexperimental=refaliasing -lwe '%a = (aa=>11,bb=>22,cc=>33); Internals::SvREADONLY(%a, 1); Internals::SvREADONLY($a{bb}, 1); print \$a{bb}; \$a{bb} = \555; print \$a{bb}'
SCALAR(0x55f3eee968a0)
SCALAR(0x55f3eefd7aa8)

>Sorry? CPAN module? Internals is a namespace reserved to perl itself or
>should be.

As I said, confusing.  It's a confusion of long standing.

>         You explained your justification for not signing up to github as
>that you consider the legal terms onerous. That justification holds for
>your own repositories, it does not hold for interacting with the rest of
>the perl developers.

Joining GitHub for any purpose would mean accepting its legal terms.
My reason for not joining GitHub applies to having an account there at
all, not to only some of the activities that would be enabled by such
an account.

-zefram

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About