Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does Perl impose string context?

Tags:

perl

It appears that string context (while a real thing, and mentioned in "Programming Perl" chapter "2.7.1. Scalar and List Context" as a sub-idea of scalar context), isn't clearly documented anywhere I was able to find on Perldoc.

Obviously, some things in Perl (e.g. eq operator, or qq// quoting interpolation) force a value into a string context.

When does Perl impose string context?

perldoc seems to contain no useful answer.

like image 982
DVK Avatar asked Feb 14 '23 03:02

DVK


1 Answers

Perl will vivify the PV (the string component) of the structure that comprises a scalar when Perl needs a string. The best place to learn about this is in perlguts, perldata, and to a lesser degree, perlop. But essentially any time a string type operation is performed with a scalar, it will impose your sense of string context, and if the scalar only contains, for example, an integer, a string will be implicitly created from that value.

So, if you have $var = 15, which places an integer in $var, and then say, if( $var eq '15' ) {...}, a string representation of the integer 15 will be generated and stored in the PV portion of the scalar's struct.

This is by no means a complete list, but the following will do the trick:

  • String comparison operators (eq, ne, ge, le, lt, gt)

  • Match binding operators for left operand (=~, !~)

  • string interpolation (qq{$var} , "$var", qx/$var/, and backticks)

  • Regex operators (m/$interpolated/, s/$interpolated//, qr/$interpolated/)

  • <<"HERE" (HERE doc with interpolation)

  • Hash key $hash{$stringified_key}.

  • . concatenation operator.

  • In newer versions of Perl, with the bitwise feature enabled, the string bitwise operators &., |., ^., and ~., along with their assignment counterparts such as &.= will invoke string context on their operands.

  • vec imposes string context on its first parameter.

There probably are others. But the good news is that this implementation detail rarely leaks to abstraction layers outside of the "guts" level. One example of where it can be a concern is when encoding JSON, since the JSON modules I am familiar with all look at whether or not a given scalar has a PV component to decide whether to encode a value as a string or a number.

As Joel identified in a comment below, the Devel::Peek module, which has been in the Perl core since Perl version 5.6.0 can facilitate introspection into the guts of a scalar:

use Devel::Peek;                    

my $foo = 12;                       

print "Initial state of \$foo:\n";  
Dump($foo);                         

my $bar = "$foo";                   

print "\n\nFinal state of \$foo:\n";
Dump($foo);                         

The output produced by that code is:

Initial state of $foo:
SV = IV(0x56547b4bb2a0) at 0x56547b4bb2b0
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 12


Final state of $foo:
SV = PVIV(0x56547b4b5880) at 0x56547b4bb2b0
  REFCNT = 1
  FLAGS = (IOK,POK,pIOK,pPOK)
  IV = 12
  PV = 0x56547b4ab600 "12"\0
  CUR = 2
  LEN = 10

As you can see, after the forced stringification there is a PV element, the POK flag is set, and the CUR and LEN fields are present to indicate the string buffer's length and the current length of its contents.

like image 130
DavidO Avatar answered Mar 04 '23 18:03

DavidO