任何人都可以向我解释这个只读的例外情况吗?

时间:2010-06-25 20:56:57

标签: perl readonly

以下是我的代码(不要担心模块顶部有USUW)

我正在测试数组ref是否只读,如果是这种情况,那么我将它复制到另一个数组ref。测试显示该数组不是只读的,但是当它运行时,它会因该错误而失败。 (对于那些不熟悉我或Smart::Comments的人 - 那些###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 
            } @_ 
            ;

这是我得到的输出:

### 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;

有人对此问题有任何熟悉吗?我们正在运行Perl 5.8.7。关于如何解决它的任何想法?

4 个答案:

答案 0 :(得分:2)

如果来自DBI::fetchrow_arrayref的引用以只读方式返回,则尝试覆盖它将无济于事:引用是只读的,而不是东西( ie ,具有列值的数组。)

如果您需要破坏性更新,请在源代码制作您自己的副本,例如

my $arg_ref = [ $sth->fetchrow_array ];

答案 1 :(得分:1)

Readonly和readonly是不同的。 (注意大写R和小写r。;-))

请参阅Scalar::Util文档了解其原因:

  

readonly SCALAR

     

如果SCALAR是只读的,则返回true。

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

这更多是关于别名(例如通过foreach循环或@_传入的别名,而不是Readonly模块。

答案 2 :(得分:1)

我想我已经弄清楚了。 Robert P是对的,但他只得到了答案的一半:Readonlyreadonly做了不同的事情,尽管他们应该做同样的事情,事实上他们不是一个错误。我会试着解释发生了什么。

Readonly有两个标量实现:一个(Readonly::XS)基于SvREADONLY标志,一个(Readonly :: Scalar)基于模仿{{1国旗。

SvREADONLY也有两个实现,一个在Perl中(它执行自我赋值并检查它是否抛出异常),一个在XS中(同样基于readonly标志)。 / p>

有4种可能的组合,不幸的是,最常见的组合(纯perl Readonly和XS只读)是唯一不能像宣传的那样工作的组合。

以下是关键:SvREADONLY实际上根本不使用sub Readonly::Readonly,只有Readonly::XS这可能是个错误sub Readonly::Scalar 正确报告该变量不是一个只读变量:它的readonlyness是由一个平局伪造的。

这是readonly IMO的错误,它应该做正确的事情,并在不能的时候记录。现在它正在做这两件事。

答案 3 :(得分:0)

看起来Scalar::Util::readonly的结果可能是 trusted 使用了你想要的方式。证人:

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.

(使用Readonly 1.03,Scalar :: Util 1.23在perl5.8.8下测试)