Home > Net >  How to check if LVALUE represents SCALAR
How to check if LVALUE represents SCALAR

Time:02-02

For years, I am using a code that contains the following condition

ref \$_[0] eq 'SCALAR'

I always expect there an ARRAY or SCALAR, but recently I passed substr() into that parameter. Unexpected things happened. The condition returned a false value.

Then I figured it out. The ref returned LVALUE instead of SCALAR.

Since LVALUE is a weird type of reference, I need to check if a scalar is behind it.

How can I check is this LVALUE represents SCALAR or not?

CodePudding user response:

An LVALUE is a special magical value that takes action when it is assigned to. So for example, calling f($hash{foo}) doesn't immediately create the foo entry in %hash; instead a temporary LVALUE is created and passed to the sub as $_[0]. If $_[0] is subsequently assigned to, that value gets stored as $hash{foo}.

An LVALUE is a scalar (i.e. it holds a single value), just an odd type of scalar.

So it's likely that the code can be fixed by just accepting both SCALAR and LVALUE as valid values. But it will depend on exactly why the check is done. It may also be that such a check is a logic error and is not actually needed, or is buggy. For example ref \$_[0] should never return ARRAY.

CodePudding user response:

Values that can be returned by reftype( $x ) (from Scalar::Util) in Perl 5.36:

Value Description Can be dereferenced?
undef The value of $x isn't a reference. No
"ARRAY" $x reference an array (a scalar of type PVAV. As an array
"HASH" $x reference a hash (a scalar of type PVHV). As a hash
"CODE" $x reference a sub (a scalar of type PVCV). As a sub
"GLOB" $x reference a glob (a scalar of type PVGV). As a glob, scalar, array, hash or code
"LVALUE" $x references a scalar of type PVLV, with some exceptions. As a scalar
"REGEXP" $x references a scalar that's a compiled regexp pattern (a scalar of type REGEXP). As a scalar
"IO" $x references a scalar that's an IO object (a scalar of type PVIO). No
"FORMAT" $x references a scalar of type PVFM. I don't know if it's possible to get a reference to a format. No
"INVLIST" $x references a scalar of type INVLIST. This is an internal type, and should never see this. No
"REF" $x references a scalar that contains a reference. As a scalar
"VSTRING" $x references a scalar that contains a version string. As a scalar
"SCALAR" $x references something else. As a scalar

Exceptions:

  • SCALAR is returned for reference to a tied PVLV.
  • REF is returned for reference to a PVLV containing a reference.

Warnings:

  • REF is returned for magical variables that currently contain a reference, and SCALAR for those that don't. But that value of magical variables can change every time you fetch it.

ref( $x ) is similar. It returns false (the special scalar, not the string false) instead of undef if the value of $x isn't a reference. If $x is a reference to something blessed, it returns the package into which it is blessed. Otherwise, it returns the same as reftype( $x ).


How can I check is this LVALUE represents SCALAR or not?

It's always a scalar.

  •  Tags:  
  • perl
  • Related