[英]How to check if LVALUE represents SCALAR
多年来,我一直在使用包含以下条件的代码
ref \$_[0] eq 'SCALAR'
我总是希望有一个ARRAY
或SCALAR
,但最近我将substr()
传递给该参数。 意想不到的事情发生了。 该条件返回了一个假值。
然后我想通了。 ref
返回LVALUE
而不是SCALAR
。
由于LVALUE
是一种奇怪的引用类型,我需要检查它后面是否有标量。
我如何检查这个LVALUE
代表SCALAR
?
LVALUE 是一种特殊的神奇值,在分配给它时会发生作用。 因此,例如,调用f($hash{foo})
不会立即在 %hash 中创建 foo 条目; 取而代之的是创建一个临时的 LVALUE 并将其作为$_[0]
传递给 sub。 如果$_[0]
随后被分配给,该值将存储为$hash{foo}
。
LVALUE 是一个标量(即它包含一个值),只是一种奇数类型的标量。
因此,很可能只需接受 SCALAR 和 LVALUE 作为有效值即可修复代码。 但这将取决于进行检查的确切原因。 也可能是这样的检查是一个逻辑错误,实际上并不需要,或者是有问题的。 例如ref \$_[0]
不应该返回 ARRAY。
Perl 5.36 中reftype( $x )
(来自 Scalar::Util)可以返回的值:
价值 | 描述 | 可以取消引用吗? |
---|---|---|
undef |
$x 的值不是参考。 |
不 |
"ARRAY" |
$x 引用一个数组(PVAV 类型的标量。 |
作为数组 |
"HASH" |
$x 引用 hash(PVHV 类型的标量)。 |
作为 hash |
"CODE" |
$x 引用一个 sub(PVCV 类型的标量)。 |
作为子 |
"GLOB" |
$x 引用一个 glob(PVGV 类型的标量)。 |
作为 glob、标量、数组、hash 或代码 |
"LVALUE" |
$x 引用 PVLV 类型的标量,但有一些例外。 |
作为标量 |
"REGEXP" |
$x 引用一个标量,它是一个已编译的正则表达式模式(一个 REGEXP 类型的标量)。 |
作为标量 |
"IO" |
$x 引用一个标量,它是 IO object(PVIO 类型的标量)。 |
不 |
"FORMAT" |
$x 引用 PVFM 类型的标量。我不知道是否有可能获得对格式的引用。 |
不 |
"INVLIST" |
$x 引用类型为 INVLIST 的标量。这是一个内部类型。 你不应该看到这个。 |
不 |
"REF" |
$x 引用包含引用的标量。 |
作为标量 |
"VSTRING" |
$x 引用包含版本字符串的标量。 |
作为标量 |
"SCALAR" |
$x 引用了其他东西。 |
作为标量 |
例外情况:
SCALAR
以引用绑定的 PVLV。REF
以引用包含引用的 PVLV。警告:
REF
为当前包含引用的魔法变量返回,而SCALAR
则为那些不包含的变量。 但是魔法变量的值在每次获取时都会发生变化。 ref( $x )
类似。 如果$x
的值不是引用,它返回false
(特殊标量,而不是字符串false
)而不是undef
。 如果$x
是对某物祝福的引用,它返回它被祝福的 package。 否则,它返回与reftype( $x )
相同的值。 我认为ref
是reftype
和blessed
的混合体。
我总是希望有一个
ARRAY
或SCALAR
reftype( \$_[0] )
永远不会是ARRAY
。
ref( \$_[0] )
可以返回ARRAY
,但前提是你做了一些奇怪的事情,比如my $x; bless( \$x, "ARRAY" ); f( $x )
my $x; bless( \$x, "ARRAY" ); f( $x )
my $x; bless( \$x, "ARRAY" ); f( $x )
。 (这就是为什么我认为它坏了。)
$_[0]
总是去一个标量。 数组元素只能是标量。 Arguments 只能是标量。
我如何检查这个
LVALUE
代表SCALAR
?
它始终是一个标量。
在您的情况下,您不需要reftype
或ref
来告诉您。 数组元素的值始终是标量,因此$_[0]
始终是标量。
如上所述,它为 PVLV 类型的标量返回。 这是一种神奇的标量。 大多数魔法标量属于 PVMG 类型,但某些类型的魔法利用 PVLV 标量提供的额外场。 PVLV 标量由$h{EXPR}
作为参数返回, pos
作为左值, substr
作为左值, vec
作为左值,等等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.