代码之家  ›  专栏  ›  技术社区  ›  Axeman maxelost

Can anybody explain this read-only exception to me?

  •  5
  • Axeman maxelost  · 技术社区  · 14 年前

    Below is my code (don't worry there's a USUW at the top of the module)

    I'm testing if an array ref is readonly, and if that is the case then I'm copying it into another array ref. The tests show that the array is not read-only, yet when it runs, it fails with that error. ( For those of you not familiar with me or Smart::Comments ——那些 ### 聪明:评论 )

    ### readonly( $arg_ref ) : readonly( $arg_ref )
    ### readonly( @$arg_ref ) : readonly( @$arg_ref )
    my @ro = map { readonly( $_ ) } @$arg_ref;
    ### @ro
    if ( readonly $arg_ref ) {
        $arg_ref = [ @$arg_ref ];
    }
    return map { my $val = shift @$arg_ref;
                 $_ => $val 
                } @_ 
                ;
    

    This is the output I get:

    ### readonly( $arg_ref ) : 0
    ### readonly( @$arg_ref ) : 0
    
    ### @ro: [
    ###        0,
    ###        0,
    ###        0,
    ###        0,
    ###        0
    ###      ]
    

    Modification of a read-only value attempted at ....pm line 247.
    

    (247):

    return map { my $val = shift @$arg_ref;
    

    )

    有人熟悉这个问题吗?我们运行的是Perl5.8.7。你知道怎么解决这个问题吗?

    4 回复  |  直到 14 年前
        1
  •  0
  •   Ether    14 年前

    It doesn't look like the result of Scalar::Util::readonly 可以是 可信的 used how you want to use it. 证人:

    perl -MScalar::Util=readonly -MReadonly -wle'
        Readonly my $arg_ref => [ qw(a b c)];
        print readonly $arg_ref;
        $arg_ref = 1;'
    

    印刷品:

    0
     Modification of a read-only value attempted at -e line 1.
    

    (Tested under perl5.8.8 with Readonly 1.03, Scalar::Util 1.23)

        2
  •  2
  •   Greg Bacon    14 年前

    If the reference from DBI::fetchrow_arrayref is coming back read-only, attempting to overwrite it won't help: the 参考 is read-only, not the thingie ( , the array with column values).

    Make your own copy right at the source if you need destructive updates, 例如 ,

    my $arg_ref = [ $sth->fetchrow_array ];
    
        3
  •  1
  •   Robert P    14 年前

    Readonly and readonly are different. (Notice the capital R and lowercase r. ;-) )

    Scalar::Util documentation for why this is true:

    只读标量

    Returns true if SCALAR is readonly.

    sub foo { readonly($_[0]) }
    $readonly = foo($bar);              # false
    $readonly = foo(0);                 # true
    

    This is more about aliases (such as those passed in via foreach loops or in @_ , and not the Readonly module.

        4
  •  1
  •   Leon Timmermans    14 年前

    I think I have it figured out. Robert P was right, but he only got half of the answer: Readonly readonly 做不同的事情,尽管他们应该做同样的事情,事实上他们没有是一个错误。我会尽力解释发生了什么事。

    只读 has two implementations for scalars: one ( Readonly::XS ) that is based on the SvREADONLY flag and one (Readonly::Scalar) based on ties that emulates the 唯读 旗帜。

    只读 还有两个实现,一个在Perl中(它执行自赋值并检查是否引发异常),另一个在XS中(同样基于 唯读 旗帜)

    有4种可能的组合,不幸的是,最常见的组合(纯PerlReadOnly和XSReadOnly)是唯一不能像广告中那样工作的组合。

    以下是症结所在: sub Readonly::Readonly actually doesn't use Readonly::XS 总之,只有 sub Readonly::Scalar 做。 This is probably a bug . 只读 正确地 报告变量不是只读变量:它的读写是由领带伪造的。

    它是 只读 that's at fault here IMO, it should do the right thing when it can and document when it can't. Right now it's doing neither of those.