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

Assigning Whole (Hash|Array) to a tied (Hash|Array) mangles SvTYPE

Thread Next
From:
Dan Kogai
Date:
March 23, 2006 16:21
Subject:
Assigning Whole (Hash|Array) to a tied (Hash|Array) mangles SvTYPE
Message ID:
AC8C2FCC-43C5-48F2-B892-5D8357F1761C@dan.co.jp
Porters,

I have found an anomaly when fiddling w/ YAML::Syck.  Perl seems to  
set IOK for (array|hash) elements when you assign the whole hash/array.

First, consider the code below;

use strict;
use warnings;
use Devel::Peek;
use Tie::Array;
my @a;
$a[0] = 1; #### 1
Dump \@a;
@a = (42); #### 2
Dump \@a;
tie @a => 'Tie::StdArray';
$a[0] = 1; #### 3
Dump \@a;
@a = (42); #### 4
Dump \@a;
__END__

The corresponding SvTYPE to $a[0] is all IOK,pIOK except for the last  
one where only pIOK is set. Detailed result right after my signature.

For NV, PV and others that did not happen.

I have noticed when I found the following code fails.

use strict;
use warnings;
use Test::More qw/no_plan/;
use YAML; # works w/ YAML but not w/ XS-based YAML::Syck
{
     use Tie::Hash;
     my $src = { a=>1, b=>'2', c=>3.1415, d=>4 };
     my $th = tie my %hash, 'Tie::StdHash';
     %hash = %$src;
     my $dst = Load(Dump($th));
     is_deeply ($dst, $src, "tied hash")
         or print Dump($dst);
}
{
     use Tie::Array;
     my $src = [ 1, '2', 3.1415, 4 ];
     my $ta = tie my @array, 'Tie::StdArray';
     @array = @$src;
     my $dst = Load(Dump($ta));
     is_deeply ($dst, $src, "tied array")
         or print Dump($dst);
}
__END__

not ok 1 - tied hash
#   Failed test 'tied hash'
#   in t/4-tied.t at line 11.
#     Structures begin differing at:
#          $got->{a} = undef
#     $expected->{a} = '1'
--- !perl/Tie::StdHash
a: ~
b: 2
c: 3.1415
d: ~
not ok 2 - tied array
#   Failed test 'tied array'
#   in t/4-tied.t at line 20.
#     Structures begin differing at:
#          $got->[0] = undef
#     $expected->[0] = '1'
--- !perl/@Tie::StdArray
- ~
- 2
- 3.1415
- ~
1..2

This seems to happen on both array and hash.  And this only happens  
when you assign to the whole array or hash.

Does it have anything to do with the fact that you do not have a  
method to assign a whole thing on Tie?  It does have CLEAR, though....

Dan the Tied to the Subtlety
================================================================
#### 1
SV = RV(0x1824844) at 0x180147c
   REFCNT = 1
   FLAGS = (TEMP,ROK)
   RV = 0x1801cc8
   SV = PVAV(0x180643c) at 0x1801cc8
     REFCNT = 2
     FLAGS = (PADBUSY,PADMY)
     IV = 0
     NV = 0
     ARRAY = 0x601870
     FILL = 0
     MAX = 3
     ARYLEN = 0x0
     FLAGS = (REAL)
     Elt No. 0
     SV = IV(0x180f9d0) at 0x1801380
       REFCNT = 1
       FLAGS = (IOK,pIOK) #### IOK,pIOK
       IV = 1
#### 2
SV = RV(0x1824844) at 0x180147c
   REFCNT = 1
   FLAGS = (TEMP,ROK)
   RV = 0x1801cc8
   SV = PVAV(0x180643c) at 0x1801cc8
     REFCNT = 2
     FLAGS = (PADBUSY,PADMY)
     IV = 0
     NV = 0
     ARRAY = 0x601870
     FILL = 0
     MAX = 3
     ARYLEN = 0x0
     FLAGS = (REAL)
     Elt No. 0
     SV = IV(0x180f9d0) at 0x1801380
       REFCNT = 1
       FLAGS = (IOK,pIOK) #### IOK,pIOK
       IV = 42
#### 3
SV = RV(0x1824848) at 0x180129c
   REFCNT = 1
   FLAGS = (TEMP,ROK)
   RV = 0x1801cc8
   SV = PVAV(0x180643c) at 0x1801cc8
     REFCNT = 2
     FLAGS = (PADBUSY,PADMY,RMG)
     IV = 0
     NV = 0
     MAGIC = 0x634d80
       MG_VIRTUAL = &PL_vtbl_pack
       MG_TYPE = PERL_MAGIC_tied(P)
       MG_FLAGS = 0x02
         REFCOUNTED
       MG_OBJ = 0x1801c98
       SV = RV(0x1824844) at 0x1801c98
         REFCNT = 1
         FLAGS = (ROK)
         RV = 0x180147c
         SV = PVAV(0x1806468) at 0x180147c
           REFCNT = 1
           FLAGS = (OBJECT)
           IV = 0
           NV = 0
           STASH = 0x1827838     "Tie::StdArray"
           ARRAY = 0x600c20
           FILL = 0
           MAX = 3
           ARYLEN = 0x0
           FLAGS = (REAL)
           Elt No. 0
           SV = PVNV(0x1804e30) at 0x182a130
             REFCNT = 1
             FLAGS = (IOK,pIOK) #### IOK,pIOK
             IV = 1
             NV = 0
             PV = 0
     ARRAY = 0x601870
     FILL = 0
     MAX = 3
     ARYLEN = 0x0
     FLAGS = (REAL)
     Elt No. 0
     SV = PVLV(0x1812120) at 0x182a13c
       REFCNT = 1
       FLAGS = (TEMP,GMG,SMG,RMG)
       IV = 0
       NV = 0
       PV = 0
       MAGIC = 0x605100
         MG_VIRTUAL = &PL_vtbl_packelem
         MG_TYPE = PERL_MAGIC_tiedelem(p)
         MG_FLAGS = 0x02
           REFCOUNTED
         MG_OBJ = 0x1801c98
         SV = RV(0x1824844) at 0x1801c98
           REFCNT = 2
           FLAGS = (ROK)
           RV = 0x180147c
           SV = PVAV(0x1806468) at 0x180147c
             REFCNT = 1
             FLAGS = (OBJECT)
             IV = 0
             NV = 0
             STASH = 0x1827838   "Tie::StdArray"
             ARRAY = 0x600c20
             FILL = 0
             MAX = 3
             ARYLEN = 0x0
             FLAGS = (REAL)
       TYPE = t
       TARGOFF = 0
       TARGLEN = 0
       TARG = 0x182a13c
#### 4
SV = RV(0x1824848) at 0x180129c
   REFCNT = 1
   FLAGS = (TEMP,ROK)
   RV = 0x1801cc8
   SV = PVAV(0x180643c) at 0x1801cc8
     REFCNT = 2
     FLAGS = (PADBUSY,PADMY,RMG)
     IV = 0
     NV = 0
     MAGIC = 0x634d80
       MG_VIRTUAL = &PL_vtbl_pack
       MG_TYPE = PERL_MAGIC_tied(P)
       MG_FLAGS = 0x02
         REFCOUNTED
       MG_OBJ = 0x1801c98
       SV = RV(0x1824844) at 0x1801c98
         REFCNT = 1
         FLAGS = (ROK)
         RV = 0x180147c
         SV = PVAV(0x1806468) at 0x180147c
           REFCNT = 1
           FLAGS = (OBJECT)
           IV = 0
           NV = 0
           STASH = 0x1827838     "Tie::StdArray"
           ARRAY = 0x600c20
           FILL = 0
           MAX = 3
           ARYLEN = 0x0
           FLAGS = (REAL)
           Elt No. 0
           SV = PVMG(0x180dee0) at 0x182a148
             REFCNT = 1
             FLAGS = (pIOK) #### Not IOK?
             IV = 42
             NV = 0
             PV = 0
     ARRAY = 0x601870
     FILL = -1
     MAX = 3
     ARYLEN = 0x0
     FLAGS = (REAL)
     Elt No. 0
     SV = PVLV(0x1812120) at 0x1801380
       REFCNT = 1
       FLAGS = (TEMP,GMG,SMG,RMG)
       IV = 0
       NV = 0
       PV = 0
       MAGIC = 0x605050
         MG_VIRTUAL = &PL_vtbl_packelem
         MG_TYPE = PERL_MAGIC_tiedelem(p)
         MG_FLAGS = 0x02
           REFCOUNTED
         MG_OBJ = 0x1801c98
         SV = RV(0x1824844) at 0x1801c98
           REFCNT = 2
           FLAGS = (ROK)
           RV = 0x180147c
           SV = PVAV(0x1806468) at 0x180147c
             REFCNT = 1
             FLAGS = (OBJECT)
             IV = 0
             NV = 0
             STASH = 0x1827838   "Tie::StdArray"
             ARRAY = 0x600c20
             FILL = 0
             MAX = 3
             ARYLEN = 0x0
             FLAGS = (REAL)
       TYPE = t
       TARGOFF = 0
       TARGLEN = 0
       TARG = 0x1801380

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