Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tieing stashes #6983

Open
p5pRT opened this issue Dec 12, 2003 · 43 comments
Open

tieing stashes #6983

p5pRT opened this issue Dec 12, 2003 · 43 comments

Comments

@p5pRT
Copy link

p5pRT commented Dec 12, 2003

Migrated from rt.perl.org#24652 (status was 'open')

Searchable as RT24652$

@p5pRT
Copy link
Author

p5pRT commented Dec 12, 2003

From tassilo.parseval@post.rwth-aachen.de

Created by tassilo.parseval@post.rwth-aachen.de

I noticed that perl wont stop you from tieing a stash​:

ethan@​ethan​:~$ perl5.8.2 -MTie​::Hash -MPOSIX=_exit -e 'tie %​:: => "Tie​::StdHash"; _exit(1)'
ethan@​ethan​:~$

When a proper shutdown via END happens, a seemingly unrelated message appears​:

ethan@​ethan​:~$ perl5.8.2 -MTie​::Hash -e 'tie %​:: => "Tie​::StdHash"'
Can't upgrade that kind of scalar during global destruction.
ethan@​ethan​:~$

Should these ties make perl croak when they happen? I can't yet see what
they could be used for especially since various perl versions behave very
differently here. Putting the tie() into a BEGIN block is a particularly
interesting experiment since functions defined in the thusly tied namespace
can't be hooked into the package any longer​:
 
  ethan@​ethan​:~$ perl5.8.2 -MTie​::Hash
  BEGIN { tie %​:: => "Tie​::StdHash"; }
  sub test {1}
  Can't upgrade that kind of scalar at - line 2.
  ^D
  Can't upgrade that kind of scalar during global destruction.

Also not bad​:

  ethan@​ethan​:~$ perl5.8.2 -MTie​::Hash
  BEGIN { tie %​:: => "Tie​::StdHash"; }
  sub test;
  Runaway prototype at - line 2.
  ^D
  Can't upgrade that kind of scalar during global destruction.

Tassilo

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl v5.8.2:

Configured by root at Fri Nov 14 07:29:04 UTC 2003.

Summary of my perl5 (revision 5.0 version 8 subversion 2) configuration:
  Platform:
    osname=linux, osvers=2.4.21, archname=i686-linux
    uname='linux ethan 2.4.21 #3 tue nov 11 09:22:00 utc 2003 i686 unknown '
    config_args=''
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O3 -march=athlon -fomit-frame-pointer -foptimize-sibling-calls -finline-functions -fstrength-reduce -frerun-loop-opt -fexpensive-optimizations -fprefetch-loop-arrays -fmove-all-movables',
    cppflags='-fno-strict-aliasing'
    ccversion='', gccversion='3.2', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -ldb -ldl -lm -lcrypt -lutil -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
    libc=/lib/libc-2.2.5.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.2.5'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    


@INC for perl v5.8.2:
    /usr/opt/perl5.8.2/lib/5.8.2/i686-linux
    /usr/opt/perl5.8.2/lib/5.8.2
    /usr/opt/perl5.8.2/lib/site_perl/5.8.2/i686-linux
    /usr/opt/perl5.8.2/lib/site_perl/5.8.2
    /usr/opt/perl5.8.2/lib/site_perl
    .


Environment for perl v5.8.2:
    HOME=/home/ethan
    LANG=C
    LANGUAGE (unset)
    LC_CTYPE=de_DE@euro
    LD_LIBRARY_PATH=:/usr/local/j2sdk1.4.0/jre/lib/i386:/usr/local/pwlib/lib:/usr/local/lib
    LOGDIR (unset)
    PATH=/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/games:/usr/local/j2re1.4.1/bin:/usr/local/mpich-1.2.5/ch_p4/bin
    PERLDOC_PAGER=/bin/less -isR
    PERL_BADLANG (unset)
    SHELL=/bin/bash


@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From tassilo.parseval@post.rwth-aachen.de

On Fri, Dec 12, 2003 at 07​:50​:04PM +0000 Tassilo v.Parseval (via RT) wrote​:

I noticed that perl wont stop you from tieing a stash​:

[...]

Should these ties make perl croak when they happen? I can't yet see what
they could be used for especially since various perl versions behave very
differently here. Putting the tie() into a BEGIN block is a particularly
interesting experiment since functions defined in the thusly tied namespace
can't be hooked into the package any longer​:

[...]

Well, in case croaking turns out to be an acceptable solution, the
attached patch against blead will achieve that. It also adds the
appropriate explanation to perldiag.pod.

Tassilo

PS​: Should patch-submitters also modify perldelta.pod accordingly or
should that be left to the patch-appliers?
--
$_=q#",}])!JAPH!qq(tsuJ[{@​"tnirp}3..0}_$;//​::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From tassilo.parseval@post.rwth-aachen.de

Inline Patch
--- pp_sys.c~	2003-10-21 09:01:45.000000000 +0200
+++ pp_sys.c	2003-12-13 09:09:26.000000000 +0100
@@ -787,6 +787,8 @@ PP(pp_tie)
     varsv = *++MARK;
     switch(SvTYPE(varsv)) {
 	case SVt_PVHV:
+        if (HvNAME((HV*)varsv))
+            Perl_croak(aTHX_ "Can't tie symbol table of package '%s'", HvNAME((HV*)varsv));
 	    methname = "TIEHASH";
 	    HvEITER((HV *)varsv) = Null(HE *);
 	    break;
--- pod/perldiag.pod~	2003-12-12 01:02:52.000000000 +0100
+++ pod/perldiag.pod	2003-12-13 09:09:36.000000000 +0100
@@ -1004,6 +1004,12 @@ negative numbers.
 negative number.  There's a Math::Complex package that comes standard
 with Perl, though, if you really want to do that.
 
+=item Can't tie symbol table of package '%s'
+
+(F) You tried to tie the symbol table of the mentioned package.
+Your script would stop working very soon if perl allowed such an 
+operation.
+
 =item Can't undef active subroutine
 
 (F) You can't undefine a routine that's currently running.  You can,

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From @rgs

Tassilo von Parseval wrote​:

On Fri, Dec 12, 2003 at 07​:50​:04PM +0000 Tassilo v.Parseval (via RT) wrote​:

I noticed that perl wont stop you from tieing a stash​:

[...]

Should these ties make perl croak when they happen? I can't yet see what
they could be used for especially since various perl versions behave very
differently here. Putting the tie() into a BEGIN block is a particularly
interesting experiment since functions defined in the thusly tied namespace
can't be hooked into the package any longer​:

[...]

Well, in case croaking turns out to be an acceptable solution, the
attached patch against blead will achieve that. It also adds the
appropriate explanation to perldiag.pod.

It seems to be good idea, to prevent doing strange things with stashes.
What happens when you mark one readonly ?

(PS - perldelta.pod patches are traditionally not considered necessary.)

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From tassilo.parseval@post.rwth-aachen.de

On Sat, Dec 13, 2003 at 09​:58​:51AM +0100 Rafael Garcia-Suarez wrote​:

Tassilo von Parseval wrote​:

On Fri, Dec 12, 2003 at 07​:50​:04PM +0000 Tassilo v.Parseval (via RT) wrote​:

I noticed that perl wont stop you from tieing a stash​:

[...]

Should these ties make perl croak when they happen? I can't yet see what
they could be used for especially since various perl versions behave very
differently here. Putting the tie() into a BEGIN block is a particularly
interesting experiment since functions defined in the thusly tied namespace
can't be hooked into the package any longer​:

[...]

Well, in case croaking turns out to be an acceptable solution, the
attached patch against blead will achieve that. It also adds the
appropriate explanation to perldiag.pod.

It seems to be good idea, to prevent doing strange things with stashes.
What happens when you mark one readonly ?

The whole stash or just the keys? When I use the lock_hash() routine
from Hash​::Util different things happen depending on when the locking
happens. In a BEGIN block​:

  ethan@​ethan​:~$ perl5.8.2 -MHash​::Util=lock_hash
  BEGIN { lock_hash(%​::) }
  sub test { print "foo\n" }
  Attempt to access disallowed key 'test' in a restricted hash at - line 2.

At run-time​:
  ethan@​ethan​:~$ perl5.8.2 -MHash​::Util=lock_hash
  lock_hash(%​::);
  sub test { print "foo\n" }
  test();
  *test1 = \&test;
  foo
  Modification of a read-only value attempted at - line 4.

Making stashes read-only (or alternatively make the core ignore
SVf_READONLY) should probably be disallowed as well, although I can see
a playground for Acme​:: modules or other exotic stuff there.

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@​"tnirp}3..0}_$;//​::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From enache@rdslink.ro

On Sat, Dec 13, 2003 a.d., Rafael Garcia-Suarez wrote​:

[...]

Should these ties make perl croak when they happen? I can't yet see what
they could be used for especially since various perl versions behave very
differently here. Putting the tie() into a BEGIN block is a particularly
interesting experiment since functions defined in the thusly tied namespace
can't be hooked into the package any longer​:
[...]
Well, in case croaking turns out to be an acceptable solution, the
attached patch against blead will achieve that. It also adds the
appropriate explanation to perldiag.pod.

It seems to be good idea, to prevent doing strange things with stashes.
What happens when you mark one readonly ?

Is the only benefit of this preventing bold and/or naive users from doing
'strange things' with Perl ? :-)

Regards,
Adi

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From @rgs

Enache Adrian wrote​:

On Sat, Dec 13, 2003 a.d., Rafael Garcia-Suarez wrote​:

[...]

Should these ties make perl croak when they happen? I can't yet see what
they could be used for especially since various perl versions behave very
differently here. Putting the tie() into a BEGIN block is a particularly
interesting experiment since functions defined in the thusly tied namespace
can't be hooked into the package any longer​:
[...]
Well, in case croaking turns out to be an acceptable solution, the
attached patch against blead will achieve that. It also adds the
appropriate explanation to perldiag.pod.

It seems to be good idea, to prevent doing strange things with stashes.
What happens when you mark one readonly ?

Is the only benefit of this preventing bold and/or naive users from doing
'strange things' with Perl ? :-)

Replace strange by broken if you want. Marking stashes readonly, OTOH,
seems perfectly sensible :)

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From tassilo.parseval@post.rwth-aachen.de

On Sat, Dec 13, 2003 at 12​:44​:16PM +0000 Adrian Enache via RT wrote​:

On Sat, Dec 13, 2003 a.d., Rafael Garcia-Suarez wrote​:

[...]

Should these ties make perl croak when they happen? I can't yet see what
they could be used for especially since various perl versions behave very
differently here. Putting the tie() into a BEGIN block is a particularly
interesting experiment since functions defined in the thusly tied namespace
can't be hooked into the package any longer​:
[...]
Well, in case croaking turns out to be an acceptable solution, the
attached patch against blead will achieve that. It also adds the
appropriate explanation to perldiag.pod.

It seems to be good idea, to prevent doing strange things with stashes.
What happens when you mark one readonly ?

Is the only benefit of this preventing bold and/or naive users from doing
'strange things' with Perl ? :-)

This goes beyond strange. No matter how hard I try, I can't make a tied
stash trigger FETCH or STORE. All I get are those 'Can't upgrade that
kind of scalar' messages. So either these errors (note that they are
marked internal in perldiag) have to go away (and measures are taken
that a stash can sensibly be tied) or we forbid it right from the start.

The second route seems to be the easier one.

As for read-onliness​: I don't quite understand how this is going to
work. Rafael, can you explain this a bit? In my understanding, a stash
must not be read-only.

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@​"tnirp}3..0}_$;//​::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From @rgs

Tassilo von Parseval wrote​:

This goes beyond strange. No matter how hard I try, I can't make a tied
stash trigger FETCH or STORE. All I get are those 'Can't upgrade that
kind of scalar' messages. So either these errors (note that they are
marked internal in perldiag) have to go away (and measures are taken
that a stash can sensibly be tied) or we forbid it right from the start.

The second route seems to be the easier one.

I'd like to understand what kind of scalar cuoldn't be upgraded.

As for read-onliness​: I don't quite understand how this is going to
work. Rafael, can you explain this a bit? In my understanding, a stash
must not be read-only.

As symbols are stored in stashes like values in regular hashes, I don't
see offhand how readonly stashes would be broken. (I didn't try, though).
"Enough rope to shoot yourself in the foot."

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From enache@rdslink.ro

On Sat, Dec 13, 2003 a.d., Tassilo von Parseval wrote​:

This goes beyond strange. No matter how hard I try, I can't make a tied
stash trigger FETCH or STORE. All I get are those 'Can't upgrade that
kind of scalar' messages. So either these errors (note that they are
marked internal in perldiag) have to go away (and measures are taken
that a stash can sensibly be tied) or we forbid it right from the start.

That message is there since the the tied hash elems were changed to LVs.
You won't get it in 5.8.0.
As of stashes acting as regular hashes wrt. tie --
IMHO, it's a real pity "tie" wasn't implemented from the start by extending
the magic virtual table.

Regards,
Adi

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From tassilo.parseval@post.rwth-aachen.de

On Sat, Dec 13, 2003 at 01​:44​:17PM +0000 Rafael Garcia-Suarez via RT wrote​:

Tassilo von Parseval wrote​:

This goes beyond strange. No matter how hard I try, I can't make a tied
stash trigger FETCH or STORE. All I get are those 'Can't upgrade that
kind of scalar' messages. So either these errors (note that they are
marked internal in perldiag) have to go away (and measures are taken
that a stash can sensibly be tied) or we forbid it right from the start.

The second route seems to be the easier one.

I'd like to understand what kind of scalar cuoldn't be upgraded.

Hmmh, this one​:

SV = PVLV(0x818c830) at 0x8149a68
  REFCNT = 1
  FLAGS = (TEMP,GMG,SMG,RMG)
  IV = 0
  NV = 0
  PV = 0
  MAGIC = 0x8151ff8
  MG_VIRTUAL = &PL_vtbl_packelem
  MG_TYPE = PERL_MAGIC_tiedelem(p)
  MG_FLAGS = 0x02
  REFCOUNTED
  MG_OBJ = 0x813ed5c
  SV = RV(0x8157da4) at 0x813ed5c
  REFCNT = 2
  FLAGS = ()
  MG_LEN = -2
  MG_PTR = 0x81499f0 => HEf_SVKEY
  SV = PV(0x813ef38) at 0x81499f0
  REFCNT = 2
  FLAGS = (POK,pPOK)
  PV = 0x814e2b0 "UNIVERSAL​::"\0
  CUR = 11
  LEN = 12
  TYPE = T
  TARGOFF = 0
  TARGLEN = 0
  TARG = 0x817c758

I don't understand where it comes from.

As for read-onliness​: I don't quite understand how this is going to
work. Rafael, can you explain this a bit? In my understanding, a stash
must not be read-only.

As symbols are stored in stashes like values in regular hashes, I don't
see offhand how readonly stashes would be broken. (I didn't try, though).
"Enough rope to shoot yourself in the foot."

The stash can be changed during the runtime of a script. This will then
no longer work​:

  eval 'sub bla { ... }';

So anything that adds something to the hash at runtime (most AUTOLOADers
for instance) would break.

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@​"tnirp}3..0}_$;//​::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From @iabyn

On Sat, Dec 13, 2003 at 04​:56​:27PM +0100, Tassilo von Parseval wrote​:

On Sat, Dec 13, 2003 at 01​:44​:17PM +0000 Rafael Garcia-Suarez via RT wrote​:

Tassilo von Parseval wrote​:

This goes beyond strange. No matter how hard I try, I can't make a tied
stash trigger FETCH or STORE. All I get are those 'Can't upgrade that
kind of scalar' messages. So either these errors (note that they are
marked internal in perldiag) have to go away (and measures are taken
that a stash can sensibly be tied) or we forbid it right from the start.

The second route seems to be the easier one.

I'd like to understand what kind of scalar cuoldn't be upgraded.

Hmmh, this one​:

SV = PVLV(0x818c830) at 0x8149a68
REFCNT = 1
FLAGS = (TEMP,GMG,SMG,RMG)
IV = 0
NV = 0
PV = 0
MAGIC = 0x8151ff8
MG_VIRTUAL = &PL_vtbl_packelem
MG_TYPE = PERL_MAGIC_tiedelem(p)
MG_FLAGS = 0x02
REFCOUNTED
MG_OBJ = 0x813ed5c
SV = RV(0x8157da4) at 0x813ed5c
REFCNT = 2
FLAGS = ()
MG_LEN = -2
MG_PTR = 0x81499f0 => HEf_SVKEY
SV = PV(0x813ef38) at 0x81499f0
REFCNT = 2
FLAGS = (POK,pPOK)
PV = 0x814e2b0 "UNIVERSAL​::"\0
CUR = 11
LEN = 12
TYPE = T
TARGOFF = 0
TARGLEN = 0
TARG = 0x817c758

I don't understand where it comes from.

That's the tempoary proxy SV used when accessing tied aggregrates (arrays
and hashes).
Since code like $a[3] = 4 doesn't do an av_store(), but rather does,
(roughly speaking),

  svp = av_fetch(av,3,lval=>1);
  ...
  sv_setsv(*svp, some_sv_with_value_4);

the only way to make tie work in this environment is for av_fetch() to
return a proxy SV with associated magic that knows what the index and
original array was; when this proxy is assigned to or accessed, the magic
causes FETCH or STORE to be called as appropriate. In the old days, this
proxy was simply a PVMG; but to fix some bugs related to FETCH accessing
things that are themselves tied, I changed it to a PVLV which has some
extra space to store values that I needed. In the case above, it's an LV
containing the proxy for a $tied_hash{'UNIVERSAL​::'} lookup.

--
To collect all the latest movies, simply place an unprotected ftp server
on the Internet, and wait for the disk to fill....

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From @scottwalters

Enough rope to let typesafety.pm do method overloading on
type signature! Wheee! I've been trying to figure out
how to get around the error when a subroutine is redefined
and how to hang onto the old code reference too without using
a source filter...

-scott

On 0, Rafael Garcia-Suarez <rgarciasuarez@​free.fr> wrote​:

Tassilo von Parseval wrote​:

This goes beyond strange. No matter how hard I try, I can't make a tied
stash trigger FETCH or STORE. All I get are those 'Can't upgrade that
kind of scalar' messages. So either these errors (note that they are
marked internal in perldiag) have to go away (and measures are taken
that a stash can sensibly be tied) or we forbid it right from the start.

The second route seems to be the easier one.

I'd like to understand what kind of scalar cuoldn't be upgraded.

As for read-onliness​: I don't quite understand how this is going to
work. Rafael, can you explain this a bit? In my understanding, a stash
must not be read-only.

As symbols are stored in stashes like values in regular hashes, I don't
see offhand how readonly stashes would be broken. (I didn't try, though).
"Enough rope to shoot yourself in the foot."

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From nick@ing-simmons.net

Tassilo Parseval <tassilo.parseval@​post.rwth-aachen.de> writes​:

It seems to be good idea, to prevent doing strange things with stashes.
What happens when you mark one readonly ?

As the readonly stuff is much closer to the guts of HVs than tie
I think we could probably make readonlyness work - i.e. give
sensible messages.

The whole stash or just the keys? When I use the lock_hash() routine
from Hash​::Util different things happen depending on when the locking
happens. In a BEGIN block​:

ethan@​ethan​:~$ perl5.8.2 -MHash​::Util=lock_hash
BEGIN { lock_hash(%​::) }
sub test { print "foo\n" }
Attempt to access disallowed key 'test' in a restricted hash at - line 2.

Seems reasonable message.

At run-time​:
ethan@​ethan​:~$ perl5.8.2 -MHash​::Util=lock_hash
lock_hash(%​::);
sub test { print "foo\n" }
test();
*test1 = \&test;
foo
Modification of a read-only value attempted at - line 4.

Less so.

Making stashes read-only (or alternatively make the core ignore
SVf_READONLY) should probably be disallowed as well, although I can see
a playground for Acme​:: modules or other exotic stuff there.

Tassilo

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From nick@ing-simmons.net

Tassilo Parseval <tassilo.parseval@​post.rwth-aachen.de> writes​:

As for read-onliness​: I don't quite understand how this is going to
work. Rafael, can you explain this a bit? In my understanding, a stash
must not be read-only.

I can imagine marking at least a sub-stash as READONLY at (say) CHECK
time as an assertion that symbol table should now be stable.
And that no run-time funny business is expected.

Tassilo

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From tassilo.parseval@post.rwth-aachen.de

On Sat, Dec 13, 2003 at 07​:06​:11PM +0000 Dave Mitchell wrote​:

On Sat, Dec 13, 2003 at 04​:56​:27PM +0100, Tassilo von Parseval wrote​:

On Sat, Dec 13, 2003 at 01​:44​:17PM +0000 Rafael Garcia-Suarez via RT wrote​:

I'd like to understand what kind of scalar cuoldn't be upgraded.

Hmmh, this one​:

SV = PVLV(0x818c830) at 0x8149a68
REFCNT = 1
FLAGS = (TEMP,GMG,SMG,RMG)
IV = 0
NV = 0
PV = 0
MAGIC = 0x8151ff8
MG_VIRTUAL = &PL_vtbl_packelem
MG_TYPE = PERL_MAGIC_tiedelem(p)
MG_FLAGS = 0x02
REFCOUNTED
MG_OBJ = 0x813ed5c
SV = RV(0x8157da4) at 0x813ed5c
REFCNT = 2
FLAGS = ()
MG_LEN = -2
MG_PTR = 0x81499f0 => HEf_SVKEY
SV = PV(0x813ef38) at 0x81499f0
REFCNT = 2
FLAGS = (POK,pPOK)
PV = 0x814e2b0 "UNIVERSAL​::"\0
CUR = 11
LEN = 12
TYPE = T
TARGOFF = 0
TARGLEN = 0
TARG = 0x817c758

I don't understand where it comes from.

That's the tempoary proxy SV used when accessing tied aggregrates (arrays
and hashes).
Since code like $a[3] = 4 doesn't do an av_store(), but rather does,
(roughly speaking),

svp = av\_fetch\(av\,3\,lval=>1\);
\.\.\.
sv\_setsv\(\*svp\, some\_sv\_with\_value\_4\);

the only way to make tie work in this environment is for av_fetch() to
return a proxy SV with associated magic that knows what the index and
original array was; when this proxy is assigned to or accessed, the magic
causes FETCH or STORE to be called as appropriate. In the old days, this
proxy was simply a PVMG; but to fix some bugs related to FETCH accessing
things that are themselves tied, I changed it to a PVLV which has some
extra space to store values that I needed. In the case above, it's an LV
containing the proxy for a $tied_hash{'UNIVERSAL​::'} lookup.

Thanks for the explanation. I didn't know any of the above yet. I still
have to find out why this UNIVERSAL​:: lookup happens and what aspect of
a stash is so special as opposed to ordinary hashes that it triggers
this behaviour.

Furthermore, we should try to come to a conclusion as to what should
become out of all this mess with tied and/or read-only stashes. Whether
being restrictive and disallow it in some way is reasonable, or whether
we prefer to go the hard route and mark it work (in some other yet to be
specified way).

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@​"tnirp}3..0}_$;//​::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?&lt;=sub).+q#q!'"qq.\t$&amp;."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2003

From @lizmat

At 21​:02 +0000 12/13/03, Nick Ing-Simmons wrote​:

Tassilo Parseval <tassilo.parseval@​post.rwth-aachen.de> writes​:

As for read-onliness​: I don't quite understand how this is going to
work. Rafael, can you explain this a bit? In my understanding, a stash
must not be read-only.
I can imagine marking at least a sub-stash as READONLY at (say) CHECK
time as an assertion that symbol table should now be stable.
And that no run-time funny business is expected.

How would that work with e.g. mod_perl? When CHECK and INIT have
already passed by the time any user module is loaded?

This is less an issue with read-onlyness (which I like by itself) and
more an issue with INIT and CHECK basically being useless. For
instance, if you create a module that depends on the usage of CHECK
or INIT, you would have to document that it won't work with mod_perl.

Liz

@p5pRT
Copy link
Author

p5pRT commented Dec 14, 2003

From nick@ing-simmons.net

Elizabeth Mattijsen <liz@​dijkmat.nl> writes​:

At 21​:02 +0000 12/13/03, Nick Ing-Simmons wrote​:

Tassilo Parseval <tassilo.parseval@​post.rwth-aachen.de> writes​:

As for read-onliness​: I don't quite understand how this is going to
work. Rafael, can you explain this a bit? In my understanding, a stash
must not be read-only.
I can imagine marking at least a sub-stash as READONLY at (say) CHECK
time as an assertion that symbol table should now be stable.
And that no run-time funny business is expected.

How would that work with e.g. mod_perl? When CHECK and INIT have
already passed by the time any user module is loaded?

It wouldn't - but as you note this is an issue with CHECK rather
than readonly.

This is less an issue with read-onlyness (which I like by itself) and
more an issue with INIT and CHECK basically being useless. For
instance, if you create a module that depends on the usage of CHECK
or INIT, you would have to document that it won't work with mod_perl.

Liz

@p5pRT
Copy link
Author

p5pRT commented Dec 14, 2003

From @ysth

On Sat, Dec 13, 2003 at 07​:06​:11PM +0000, Dave Mitchell <davem@​fdgroup.com> wrote​:

the only way to make tie work in this environment is for av_fetch() to
return a proxy SV with associated magic that knows what the index and
original array was; when this proxy is assigned to or accessed, the magic
causes FETCH or STORE to be called as appropriate. In the old days, this
proxy was simply a PVMG; but to fix some bugs related to FETCH accessing
things that are themselves tied, I changed it to a PVLV which has some
extra space to store values that I needed. In the case above, it's an LV
containing the proxy for a $tied_hash{'UNIVERSAL​::'} lookup.

Not good. You can't store a fake glob in a tied hash anymore​:

$ perl -we'use Tie​::Hash; tie %h, "Tie​::StdHash"; $h{foo} = *STDOUT; use Devel​:
:Peek; Dump $h{foo}'
Can't upgrade that kind of scalar at -e line 1.

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 2003

From rick@bort.ca

On Sat, Dec 13, 2003 at 04​:17​:06PM +0200, Enache Adrian wrote​:

IMHO, it's a real pity "tie" wasn't implemented from the start by extending
the magic virtual table.

Aside from tuits, is there any reason why this couldn't be done now?
I'm reminded of this mini-patch by Doug MacEachern​:

  http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2001-11/msg00203.html

which provides an alternative to tie. It doesn't support all the ops
but I can't help but feel that with the right hooks both tie and
overload could be moved out of the core and then competing
implementations could provide the missing functionality without
involving p5p.

--
Rick Delaney
rick@​bort.ca

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 2003

From tassilo.parseval@post.rwth-aachen.de

On Sun, Dec 14, 2003 at 11​:27​:38PM -0500 Rick Delaney wrote​:

On Sat, Dec 13, 2003 at 04​:17​:06PM +0200, Enache Adrian wrote​:

IMHO, it's a real pity "tie" wasn't implemented from the start by extending
the magic virtual table.

Aside from tuits, is there any reason why this couldn't be done now?
I'm reminded of this mini-patch by Doug MacEachern​:

http&#8203;://www\.xray\.mpe\.mpg\.de/mailing\-lists/perl5\-porters/2001\-11/msg00203\.html

which provides an alternative to tie. It doesn't support all the ops
but I can't help but feel that with the right hooks both tie and
overload could be moved out of the core and then competing
implementations could provide the missing functionality without
involving p5p.

This sounds a little like old wine in new containers. As I see it, the
problem with tie (in fact with any attached magic) is that these magic
virtual tables just hold five function pointers.

What I'd like to see (for tied hashes) is this​:

  EXT MGVTBL_EXTENDED PL_vtbl_tiedhash = {
  MEMBER_TO_FPTR(Perl_magic_store),
  MEMBER_TO_FPTR(Perl_magic_fetch),
  MEMBER_TO_FPTR(Perl_magic_exists),
  /* and so on for each method of a tied a hash */
  ...
  };

This would also solve the problem of implementing a tied hash in XS
since all that would be needed is creating one's own MGVTBL_EXTEND
structure with pointers to custom C funtions in it and replace the
default table (PL_vtbl_tiedhash) with the thusly created one.

Right now this is impossible because the majority of the tied
functionality is directly hooked into the various OPs. No chance of
accessing it from XS. One needs the cumbersome indirection of
implementing the STORE, FETCH etc. methods in XS. This furthermore has
the disadvantage of inefficiency.

If we are really considering to reimplement the innards of tied hashes
(and arrays and scalars), I agree with Adi that a full virtual table
approach should be chosen. I am also quite sure that it would suffer
less from all those strange sife-effects that tieing has right now.

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@​"tnirp}3..0}_$;//​::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?&lt;=sub).+q#q!'"qq.\t$&amp;."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 2003

From @lizmat

At 08​:28 +0100 12/15/03, Tassilo von Parseval wrote​:

If we are really considering to reimplement the innards of tied hashes
(and arrays and scalars), I agree with Adi that a full virtual table
approach should be chosen. I am also quite sure that it would suffer
less from all those strange sife-effects that tieing has right now.

What you describe here, is called "Ponie" to a large extent (the way
I understand it). Perl5 using Parrot's vtable approach for its
innards.

Liz

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 2003

From tassilo.parseval@post.rwth-aachen.de

On Mon, Dec 15, 2003 at 08​:40​:22AM +0100 Elizabeth Mattijsen wrote​:

At 08​:28 +0100 12/15/03, Tassilo von Parseval wrote​:

If we are really considering to reimplement the innards of tied hashes
(and arrays and scalars), I agree with Adi that a full virtual table
approach should be chosen. I am also quite sure that it would suffer
less from all those strange sife-effects that tieing has right now.

What you describe here, is called "Ponie" to a large extent (the way
I understand it). Perl5 using Parrot's vtable approach for its
innards.

I hope this isn't used as an argument against extending the virtual
table. :-)

Just for fun, I am right now adding MGVTBLX to the core. That's going to
be a structure which holds 14 pointers to functions where each one
triggers one of the methods in a tieing class. I am eager to see where
it gets me and whether it is feasible in a reasonable extent.

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@​"tnirp}3..0}_$;//​::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?&lt;=sub).+q#q!'"qq.\t$&amp;."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 2003

From @lizmat

At 09​:26 +0100 12/15/03, Tassilo von Parseval wrote​:

On Mon, Dec 15, 2003 at 08​:40​:22AM +0100 Elizabeth Mattijsen wrote​:

What you describe here, is called "Ponie" to a large extent (the way
I understand it). Perl5 using Parrot's vtable approach for its
innards.
I hope this isn't used as an argument against extending the virtual
table. :-)

Yes and no. One the one hand, I wouldn't dream about telling anybody
not to do anything.

On the other hand, when Ponie comes around, your work may not be
usable/used in Perl.

Personally, I always try to find solace in the fact that with any
work, whether it was used or not, getting there taught me something
to make it worthwhile by itself.

Liz

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 2003

From @hvds

Rafael Garcia-Suarez <rgarciasuarez@​free.fr> wrote​:
:Enache Adrian wrote​:
:> On Sat, Dec 13, 2003 a.d., Rafael Garcia-Suarez wrote​:
:> > > [...]
:> > > > Should these ties make perl croak when they happen? I can't yet see what
:> > > > they could be used for especially since various perl versions behave very
:> > > > differently here. Putting the tie() into a BEGIN block is a particularly
:> > > > interesting experiment since functions defined in the thusly tied namespace
:> > > > can't be hooked into the package any longer​:
:> > > [...]
:> > > Well, in case croaking turns out to be an acceptable solution, the
:> > > attached patch against blead will achieve that. It also adds the
:> > > appropriate explanation to perldiag.pod.
:> >
:> > It seems to be good idea, to prevent doing strange things with stashes.
:> > What happens when you mark one readonly ?
:>
:> Is the only benefit of this preventing bold and/or naive users from doing
:> 'strange things' with Perl ? :-)
:
:Replace strange by broken if you want. Marking stashes readonly, OTOH,
:seems perfectly sensible :)

I agree​: attempting to tie a stash should croak at least until we can
make it do something remotely sensible, but I think there is value in
letting them be readonly.

Hugo

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 2003

From rick@bort.ca

On Mon, Dec 15, 2003 at 08​:28​:23AM +0100, Tassilo von Parseval wrote​:

On Sun, Dec 14, 2003 at 11​:27​:38PM -0500 Rick Delaney wrote​:

On Sat, Dec 13, 2003 at 04​:17​:06PM +0200, Enache Adrian wrote​:

IMHO, it's a real pity "tie" wasn't implemented from the start by extending
the magic virtual table.

Aside from tuits, is there any reason why this couldn't be done now?
I'm reminded of this mini-patch by Doug MacEachern​:

http&#8203;://www\.xray\.mpe\.mpg\.de/mailing\-lists/perl5\-porters/2001\-11/msg00203\.html

which provides an alternative to tie. It doesn't support all the ops
but I can't help but feel that with the right hooks both tie and
overload could be moved out of the core and then competing
implementations could provide the missing functionality without
involving p5p.

This sounds a little like old wine in new containers. As I see it, the
problem with tie (in fact with any attached magic) is that these magic
virtual tables just hold five function pointers.

I don't think I suggested Doug's patch would solve any of the recently
discussed problems. I mentioned it because it is a nice, neat example
of adding tie-like functionality without touching the existing tie mess.

Anyway, as I see it the bigger problem with tie is not the current
implementation, but that it can't be extended without breaking things
(eg. FETCHSLICE). I think the only solution to this is an alternate
API.

What I'd like to see (for tied hashes) is this​:

EXT MGVTBL\_EXTENDED PL\_vtbl\_tiedhash = \{
    MEMBER\_TO\_FPTR\(Perl\_magic\_store\)\,
    MEMBER\_TO\_FPTR\(Perl\_magic\_fetch\)\,
    MEMBER\_TO\_FPTR\(Perl\_magic\_exists\)\,
    /\* and so on for each method of a tied a hash \*/
    \.\.\.
\};

Sure, whatever. I'll ask again​:

Aside from tuits, is there any reason why this couldn't be done now?

I ask because I don't know enough about this area of the internals to know
if this would result in more complex perl-core code or performance problems
or what. Wouldn't each pp_op need code at the beginning to allow the
user function to intercept the operation (like overload does now) when
the op is called on a tied thingy? If so, then I see no reason why this
couldn't be generalized to deal with overload as well as tie.

--
Rick Delaney
rick@​bort.ca

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 2003

From nick.ing-simmons@elixent.com

Rick Delaney <rick@​bort.ca> writes​:

On Sat, Dec 13, 2003 at 04​:17​:06PM +0200, Enache Adrian wrote​:

IMHO, it's a real pity "tie" wasn't implemented from the start by extending
the magic virtual table.

Aside from tuits, is there any reason why this couldn't be done now?

It _is_ being done now. This kind of tidy up is exactly what perl6 is about.

Re-doing tie in perl5 another way is I suppose possible, but perl5 needs
to support a pile of legacy CPAN modules which do it the way it is.

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 2003

From @iabyn

On Sun, Dec 14, 2003 at 01​:28​:22PM -0800, Yitzchak Scott-Thoennes wrote​:

On Sat, Dec 13, 2003 at 07​:06​:11PM +0000, Dave Mitchell <davem@​fdgroup.com> wrote​:

the only way to make tie work in this environment is for av_fetch() to
return a proxy SV with associated magic that knows what the index and
original array was; when this proxy is assigned to or accessed, the magic
causes FETCH or STORE to be called as appropriate. In the old days, this
proxy was simply a PVMG; but to fix some bugs related to FETCH accessing
things that are themselves tied, I changed it to a PVLV which has some
extra space to store values that I needed. In the case above, it's an LV
containing the proxy for a $tied_hash{'UNIVERSAL​::'} lookup.

Not good. You can't store a fake glob in a tied hash anymore​:

$ perl -we'use Tie​::Hash; tie %h, "Tie​::StdHash"; $h{foo} = *STDOUT; use Devel​:
:Peek; Dump $h{foo}'
Can't upgrade that kind of scalar at -e line 1.

You can get a similar effect without tiedness (but with lvalues)​:

$ perl5.8.0 -wle 'sub f { $_[0] = *STDOUT } my %h; f($h{a})'
Can't upgrade that kind of scalar at -e line 1.

So should lvlaues be fixed in some way, or was it plain wrong to use LVs
to solve tie problems?

--
A walk of a thousand miles begins with a single step...
then continues for another 1,999,999 or so.

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 2003

From tassilo.parseval@post.rwth-aachen.de

On Mon, Dec 15, 2003 at 10​:31​:13AM +0000 hv@​crypt.org wrote​:

Rafael Garcia-Suarez <rgarciasuarez@​free.fr> wrote​:

:Replace strange by broken if you want. Marking stashes readonly, OTOH,
:seems perfectly sensible :)

I agree​: attempting to tie a stash should croak at least until we can
make it do something remotely sensible, but I think there is value in
letting them be readonly.

So far all my attempts in finding out how a read-only stash could
possibly work have been in vain. How would a read-only stash behave
towards a construct such as

  sub AUTOLOAD {
  ...
  *$AUTOLOAD = eval "sub { ... }";
  ...
  }

? Aren't those additions to the stash happening at run-time?

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@​"tnirp}3..0}_$;//​::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?&lt;=sub).+q#q!'"qq.\t$&amp;."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 2003

From tassilo.parseval@post.rwth-aachen.de

On Mon, Dec 15, 2003 at 05​:51​:19PM +0000 Nick Ing-Simmons wrote​:

Rick Delaney <rick@​bort.ca> writes​:

On Sat, Dec 13, 2003 at 04​:17​:06PM +0200, Enache Adrian wrote​:

IMHO, it's a real pity "tie" wasn't implemented from the start by extending
the magic virtual table.

Aside from tuits, is there any reason why this couldn't be done now?

It _is_ being done now. This kind of tidy up is exactly what perl6 is about.

Re-doing tie in perl5 another way is I suppose possible, but perl5 needs
to support a pile of legacy CPAN modules which do it the way it is.

I think a new implementation would only expose those code to
incompatabilities that manually replaced the PL_vtbl_pack magic of a
variable with a new custom one. I think this is a) extremely rare and b)
in wild discordance with what perlguts says about magicness. As I
understand it, there has never really been a proper interface to the
innards of the magic stuff, except maybe the 'U' and '~' magic.

All the above however leads us astray. I don't think it's very likely
(or even desirable) to replace the whole PERL_MAGIC_pack with something
more sensible in 5.10. The next major release after 5.10 will be ponie
anyway and chances that a new implementation will have its own problems
and bugs at the beginning quite high, too.

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@​"tnirp}3..0}_$;//​::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?&lt;=sub).+q#q!'"qq.\t$&amp;."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 2003

From @lizmat

At 22​:24 +0100 12/15/03, Tassilo von Parseval wrote​:

So far all my attempts in finding out how a read-only stash could
possibly work have been in vain. How would a read-only stash behave
towards a construct such as

sub AUTOLOAD \{
    \.\.\.
    \*$AUTOLOAD = eval "sub \{ \.\.\. \}";
    \.\.\.
\}

? Aren't those additions to the stash happening at run-time?

Indeed. That's something you can't do then. The same would
presumably apply to a string eval with "sub $AUTOLOAD { }". Or
anything that would create a new global scalar, array, hash, glob or
format, unless there was a similarly named scalar,array,hash,glob or
format already ;-)

Liz

@p5pRT
Copy link
Author

p5pRT commented Dec 15, 2003

From @scottwalters

Let me be more clear - if you nice folks make stashes tieable with
the tied-hash API, I'll make typesafety do method overloading on
method signature.

Again, I've wanted that feature for a while (as do a lot of people)
but I haven't had a clean way to do it yet.

Cheers!
-scott

On 0, Elizabeth Mattijsen <liz@​dijkmat.nl> wrote​:

At 22​:24 +0100 12/15/03, Tassilo von Parseval wrote​:

So far all my attempts in finding out how a read-only stash could
possibly work have been in vain. How would a read-only stash behave
towards a construct such as

sub AUTOLOAD \{
    \.\.\.
    \*$AUTOLOAD = eval "sub \{ \.\.\. \}";
    \.\.\.
\}

? Aren't those additions to the stash happening at run-time?

Indeed. That's something you can't do then. The same would
presumably apply to a string eval with "sub $AUTOLOAD { }". Or
anything that would create a new global scalar, array, hash, glob or
format, unless there was a similarly named scalar,array,hash,glob or
format already ;-)

Liz

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 2003

From nick.ing-simmons@elixent.com

Tassilo Parseval <tassilo.parseval@​post.rwth-aachen.de> writes​:

On Mon, Dec 15, 2003 at 08​:40​:22AM +0100 Elizabeth Mattijsen wrote​:

At 08​:28 +0100 12/15/03, Tassilo von Parseval wrote​:

If we are really considering to reimplement the innards of tied hashes
(and arrays and scalars), I agree with Adi that a full virtual table
approach should be chosen. I am also quite sure that it would suffer
less from all those strange sife-effects that tieing has right now.

What you describe here, is called "Ponie" to a large extent (the way
I understand it). Perl5 using Parrot's vtable approach for its
innards.

I hope this isn't used as an argument against extending the virtual
table. :-)

Well you can count me as arguing that way. Existing XS modules which
use MAGIC * may have

MGVTBL TkGlue_vtab = { ... }

and similar - those need to continue to work.

Just for fun, I am right now adding MGVTBLX to the core. That's going to
be a structure which holds 14 pointers to functions where each one
triggers one of the methods in a tieing class. I am eager to see where
it gets me and whether it is feasible in a reasonable extent.

I quick grep of perltie.pod shows 25 method names not counting
TIEXXXX - which subset are your 14?

=item CLEAR this
=item CLOSE this
=item DELETE this, key
=item DESTROY this
=item EXISTS this, key
=item EXTEND this, count
=item FETCH this
=item FETCHSIZE this
=item FIRSTKEY this
=item GETC this
=item NEXTKEY this, lastkey
=item POP this
=item PRINT this, LIST
=item PRINTF this, LIST
=item PUSH this, LIST
=item READ this, LIST
=item READLINE this
=item SCALAR this
=item SHIFT this
=item SPLICE this, offset, length, LIST
=item STORE this, index, value
=item STORESIZE this, count
=item UNSHIFT this, LIST
=item UNTIE this
=item WRITE this, LIST

Tassilo

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 2003

From nick.ing-simmons@elixent.com

Tassilo Parseval <tassilo.parseval@​post.rwth-aachen.de> writes​:

On Mon, Dec 15, 2003 at 10​:31​:13AM +0000 hv@​crypt.org wrote​:

Rafael Garcia-Suarez <rgarciasuarez@​free.fr> wrote​:

:Replace strange by broken if you want. Marking stashes readonly, OTOH,
:seems perfectly sensible :)

I agree​: attempting to tie a stash should croak at least until we can
make it do something remotely sensible, but I think there is value in
letting them be readonly.

So far all my attempts in finding out how a read-only stash could
possibly work have been in vain. How would a read-only stash behave
towards a construct such as

sub AUTOLOAD {
...
*$AUTOLOAD = eval "sub { ... }";
...
}

? Aren't those additions to the stash happening at run-time?

Yes. That is just the kind of thing a readonly stash could be used
to disallow.

Tassilo

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 2003

From nick.ing-simmons@elixent.com

Tassilo Parseval <tassilo.parseval@​post.rwth-aachen.de> writes​:

On Mon, Dec 15, 2003 at 05​:51​:19PM +0000 Nick Ing-Simmons wrote​:

Rick Delaney <rick@​bort.ca> writes​:

On Sat, Dec 13, 2003 at 04​:17​:06PM +0200, Enache Adrian wrote​:

IMHO, it's a real pity "tie" wasn't implemented from the start by extending
the magic virtual table.

Aside from tuits, is there any reason why this couldn't be done now?

It _is_ being done now. This kind of tidy up is exactly what perl6 is about.

Re-doing tie in perl5 another way is I suppose possible, but perl5 needs
to support a pile of legacy CPAN modules which do it the way it is.

I think a new implementation would only expose those code to
incompatabilities that manually replaced the PL_vtbl_pack magic of a
variable with a new custom one. I think this is a) extremely rare

It isn't rare - my guess is that most XS modules that use MAGIC
do that - I know Tk does.

and b)
in wild discordance with what perlguts says about magicness. As I
understand it, there has never really been a proper interface to the
innards of the magic stuff, except maybe the 'U' and '~' magic.

Which are the ones that XS uses and '~' magic in particular
does not set a vtable.

All the above however leads us astray. I don't think it's very likely
(or even desirable) to replace the whole PERL_MAGIC_pack with something
more sensible in 5.10. The next major release after 5.10 will be ponie
anyway and chances that a new implementation will have its own problems
and bugs at the beginning quite high, too.

Tassilo

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 2003

From tassilo.parseval@post.rwth-aachen.de

On Tue, Dec 16, 2003 at 04​:22​:11PM +0000 Nick Ing-Simmons wrote​:

Tassilo Parseval <tassilo.parseval@​post.rwth-aachen.de> writes​:

On Mon, Dec 15, 2003 at 08​:40​:22AM +0100 Elizabeth Mattijsen wrote​:

At 08​:28 +0100 12/15/03, Tassilo von Parseval wrote​:

If we are really considering to reimplement the innards of tied hashes
(and arrays and scalars), I agree with Adi that a full virtual table
approach should be chosen. I am also quite sure that it would suffer
less from all those strange sife-effects that tieing has right now.

What you describe here, is called "Ponie" to a large extent (the way
I understand it). Perl5 using Parrot's vtable approach for its
innards.

I hope this isn't used as an argument against extending the virtual
table. :-)

Well you can count me as arguing that way. Existing XS modules which
use MAGIC * may have

MGVTBL TkGlue_vtab = { ... }

and similar - those need to continue to work.

As long as they are not of type PERL_MAGIC_tied, they should. :-)

To make it fully backwards-compatible (even with tied variables), it
might become necessary to introduce a new type, maybe PERL_MAGIC_tiedvt,
which gets used throughout the core for all tied variables.

PERL_MAGIC_tied would remain what it is now for those extension that
directly fiddle with the involved magic.

Just for fun, I am right now adding MGVTBLX to the core. That's going to
be a structure which holds 14 pointers to functions where each one
triggers one of the methods in a tieing class. I am eager to see where
it gets me and whether it is feasible in a reasonable extent.

I quick grep of perltie.pod shows 25 method names not counting
TIEXXXX - which subset are your 14?

=item CLEAR this
=item CLOSE this
=item DELETE this, key
=item DESTROY this
=item EXISTS this, key
=item EXTEND this, count
=item FETCH this
=item FETCHSIZE this
=item FIRSTKEY this
=item GETC this
=item NEXTKEY this, lastkey
=item POP this
=item PRINT this, LIST
=item PRINTF this, LIST
=item PUSH this, LIST
=item READ this, LIST
=item READLINE this
=item SCALAR this
=item SHIFT this
=item SPLICE this, offset, length, LIST
=item STORE this, index, value
=item STORESIZE this, count
=item UNSHIFT this, LIST
=item UNTIE this
=item WRITE this, LIST

Oups, forgot FIRSTKEY and NEXTKEY. Not a big deal since so far
only EXISTS works. ;-) I am having a hard struggle with FETCH and STORE
which seem to be the toughest. I haven't yet fully grokked
PERL_MAGIC_tiedelem and how this proxy element that is created in
S_hv_fetch_common works.

The other ones that are missing are all methods of a tied handle since I
haven't yet looked into those. In the end I might be recycling some
pointers because no variable type needs all of those 25 methods. On the
other hand, a virtual table only exists once in memory so its size
shouldn't be a concern.

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@​"tnirp}3..0}_$;//​::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?&lt;=sub).+q#q!'"qq.\t$&amp;."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 2003

From tassilo.parseval@post.rwth-aachen.de

On Tue, Dec 16, 2003 at 04​:38​:24PM +0000 Nick Ing-Simmons wrote​:

Tassilo Parseval <tassilo.parseval@​post.rwth-aachen.de> writes​:

On Mon, Dec 15, 2003 at 10​:31​:13AM +0000 hv@​crypt.org wrote​:

Rafael Garcia-Suarez <rgarciasuarez@​free.fr> wrote​:

:Replace strange by broken if you want. Marking stashes readonly, OTOH,
:seems perfectly sensible :)

I agree​: attempting to tie a stash should croak at least until we can
make it do something remotely sensible, but I think there is value in
letting them be readonly.

So far all my attempts in finding out how a read-only stash could
possibly work have been in vain. How would a read-only stash behave
towards a construct such as

sub AUTOLOAD {
...
*$AUTOLOAD = eval "sub { ... }";
...
}

? Aren't those additions to the stash happening at run-time?

Yes. That is just the kind of thing a readonly stash could be used
to disallow.

I don't think we want to disallow anything that works perfectly well.
The initial topic was tieing of stashes which I suggested to disallow
because it screws up everything. I guess I missed this shift in topic.
;-)

The read-onlyness can already be done now, namely by turning a stash
into a restricted hash with Hash​::Util, preferably at CHECK time.

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@​"tnirp}3..0}_$;//​::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?&lt;=sub).+q#q!'"qq.\t$&amp;."'!#+sexisexiixesixeseg;y~\n~~dddd;eval

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 2003

From @lizmat

At 18​:06 +0100 12/16/03, Tassilo von Parseval wrote​:

Yes. That is just the kind of thing a readonly stash could be used
to disallow.
The read-onlyness can already be done now, namely by turning a stash
into a restricted hash with Hash​::Util, preferably at CHECK time.

But, as I already tried to point out, CHECK is pretty useless for that.

Suppose I'm an author of a CPAN module who wants to make sure that
nothing happens within the package's namespace. How would I do that?
Well, by making the package's stash read only at CHECK time. Fine.
And then somebody uses the module in mod_perl. And then suddenly,
the stash is not read-only anymore. Instead you get a very "useful"
warning that it is too late to run CHECK. ;-(

Liz

@p5pRT
Copy link
Author

p5pRT commented Dec 22, 2003

From nick.ing-simmons@elixent.com

Tassilo Parseval <tassilo.parseval@​post.rwth-aachen.de> writes​:

On Tue, Dec 16, 2003 at 04​:38​:24PM +0000 Nick Ing-Simmons wrote​:

Tassilo Parseval <tassilo.parseval@​post.rwth-aachen.de> writes​:

On Mon, Dec 15, 2003 at 10​:31​:13AM +0000 hv@​crypt.org wrote​:

Rafael Garcia-Suarez <rgarciasuarez@​free.fr> wrote​:

:Replace strange by broken if you want. Marking stashes readonly, OTOH,
:seems perfectly sensible :)

I agree​: attempting to tie a stash should croak at least until we can
make it do something remotely sensible, but I think there is value in
letting them be readonly.

So far all my attempts in finding out how a read-only stash could
possibly work have been in vain. How would a read-only stash behave
towards a construct such as

sub AUTOLOAD {
...
*$AUTOLOAD = eval "sub { ... }";
...
}

? Aren't those additions to the stash happening at run-time?

Yes. That is just the kind of thing a readonly stash could be used
to disallow.

I don't think we want to disallow anything that works perfectly well.

What I meant is that the MAIN use I can see for a readonly stash is
as a policing tool that once turned on complains if other code
messes with the stash - e.g. once turned on AUTOLOAD into that stash
is considered "wrong". This could be used as a check that all subs
had proper stubs etc.

The initial topic was tieing of stashes which I suggested to disallow
because it screws up everything. I guess I missed this shift in topic.
;-)

The read-onlyness can already be done now, namely by turning a stash
into a restricted hash with Hash​::Util, preferably at CHECK time.

Tassilo

@p5pRT
Copy link
Author

p5pRT commented Dec 29, 2003

@rspier - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jul 5, 2012

From @doy

The examples given in the original post no longer cause that warning,
but tying
stashes still doesn't work. Also, this slight modification of the initial
example segfaults​:

  BEGIN {
  require Tie​::Hash;
  tie %Foo​:: => "Tie​::StdHash";
  }
  package Foo;
  *baz = sub { };

-doy

@p5pRT
Copy link
Author

p5pRT commented Jul 8, 2012

From @rurban

On Thu, Jul 5, 2012 at 3​:03 PM, Jesse Luehrs via RT
<perlbug-followup@​perl.org> wrote​:

The examples given in the original post no longer cause that warning,
but tying
stashes still doesn't work. Also, this slight modification of the initial
example segfaults​:

BEGIN {
require Tie​::Hash;
tie %Foo​:: => "Tie​::StdHash";
}
package Foo;
*baz = sub { };

1. To tie a stash should either fail (best compile-time), or we need
to make it work.
Making it work will cause a slow-down, adding magic checks for each
stash access.
My vote would be no. Nobody is using it, it will make the implementation
complicated and it will hurt general performance, for the benefit of
weird corner cases nobody is needing.

2. The whole readonly-stash discussion in 2003 was a bit odd.
Allowing readonly stashes allows perfectly fine compile-time optimizations,
esp. to short-cut method calls, but also for the MOP and general class
optimizations.
The analogy to Moose make_immutable(), just in core.

There is just no sanctioned syntax for it. Damian thought of
  package NAME :const,
I am more leaning to
  const package NAME {}
as most attributes have no compile-time hook, only run-time, and are as such
unusable as type-qualifiers to allow compile-time optimizations.
--
Reini Urban
http​://cpanel.net/ http​://www.perl-compiler.org/

@p5pRT
Copy link
Author

p5pRT commented Jul 8, 2012

From @Leont

On Sun, Jul 8, 2012 at 7​:35 PM, Reini Urban <rurban@​x-ray.at> wrote​:

2. The whole readonly-stash discussion in 2003 was a bit odd.
Allowing readonly stashes allows perfectly fine compile-time optimizations,
esp. to short-cut method calls, but also for the MOP and general class
optimizations.

Right now we don't even have proper read-only hashes IMHO. The
SVf_READONLY flag on hashes means restricted instead of read-only.
This is almost the same, except for reading a non-existent key not
being allowed (instead of just returning undef). I think this would be
rather problematic for stashes too. (I've been considering fixing that
when tuits permit, but then I'd have to find a solution to support
restricted hashes).

Leon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants