Skip to content

Commit 04f5631

Browse files
committed
perldelta entry for the PV/IV flags changes.
This needs an update to known_pod_issues.dat because the Pod has trailing whitespace to avoid parts of the same verbatim code block getting separated.
1 parent 41f0846 commit 04f5631

File tree

2 files changed

+114
-1
lines changed

2 files changed

+114
-1
lines changed

pod/perldelta.pod

Lines changed: 113 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,119 @@ well.
348348

349349
=item *
350350

351-
XXX
351+
Reading the string form of an integer value no longer sets the flag C<SVf_POK>.
352+
The string form is still cached internally, and still re-read directly by the
353+
macros C<SvPV(sv)> I<etc> (inline, without calling a C function). XS code that
354+
already the APIs to get values will not be affected by this change. XS code
355+
that accesses flags directly instead of using API calls to express its intent
356+
I<might> break, but such code likely is already buggy if passed some other
357+
values, such as floating point values or objects with string overloading.
358+
359+
This small change permits code (such as JSON serealisers) to reliably determine
360+
between
361+
362+
=over 4
363+
364+
=item *
365+
366+
a value that was initially B<written> as an integer, but then B<read> as a string
367+
368+
my $answer = 42;
369+
print "The answer is $answer\n";
370+
371+
=item *
372+
373+
that same value that was initially B<written> as a string, but then B<read> as an integer
374+
375+
my $answer = "42";
376+
print "That doesn't look right\n"
377+
unless $answer == 6 * 9;
378+
379+
=back
380+
381+
For the first case (originally written as an integer), we now have:
382+
383+
use Devel::Peek;
384+
my $answer = 42;
385+
Dump ($answer);
386+
my $void = "$answer";
387+
print STDERR "\n";
388+
Dump($answer)
389+
390+
391+
SV = IV(0x562538925778) at 0x562538925788
392+
REFCNT = 1
393+
FLAGS = (IOK,pIOK)
394+
IV = 42
395+
396+
SV = PVIV(0x5625389263c0) at 0x562538925788
397+
REFCNT = 1
398+
FLAGS = (IOK,pIOK,pPOK)
399+
IV = 42
400+
PV = 0x562538919b50 "42"\0
401+
CUR = 2
402+
LEN = 10
403+
404+
For the second (originally written as a string), we now have:
405+
406+
use Devel::Peek;
407+
my $answer = "42";
408+
Dump ($answer);
409+
my $void = $answer == 6 * 9;
410+
print STDERR "\n";
411+
Dump($answer)'
412+
413+
414+
SV = PV(0x5586ffe9bfb0) at 0x5586ffec0788
415+
REFCNT = 1
416+
FLAGS = (POK,IsCOW,pPOK)
417+
PV = 0x5586ffee7fd0 "42"\0
418+
CUR = 2
419+
LEN = 10
420+
COW_REFCNT = 1
421+
422+
SV = PVIV(0x5586ffec13c0) at 0x5586ffec0788
423+
REFCNT = 1
424+
FLAGS = (IOK,POK,IsCOW,pIOK,pPOK)
425+
IV = 42
426+
PV = 0x5586ffee7fd0 "42"\0
427+
CUR = 2
428+
LEN = 10
429+
COW_REFCNT = 1
430+
431+
(One can't rely on the presence or absence of the flag C<SVf_IsCOW> to
432+
determine the history of operations on a scalar.)
433+
434+
Previously both cases would be indistinguishable, with all 4 flags set:
435+
436+
SV = PVIV(0x55d4d62edaf0) at 0x55d4d62f0930
437+
REFCNT = 1
438+
FLAGS = (IOK,POK,pIOK,pPOK)
439+
IV = 42
440+
PV = 0x55d4d62e1740 "42"\0
441+
CUR = 2
442+
LEN = 10
443+
444+
(and possibly C<SVf_IsCOW>, but not always)
445+
446+
This now means that if XS code I<really> needs to determine which form a value
447+
was first written as, it should implement logic roughly
448+
449+
if (flags & SVf_IOK|SVf_NOK) && !(flags & SVf_POK)
450+
serealise as number
451+
else if (flags & SVf_POK)
452+
serealise as string
453+
else
454+
the existing guesswork ...
455+
456+
Note that this doesn't cover "dualvars" - scalars that report different
457+
values when asked for their string form or number form (such as C<$!>).
458+
Most serialisation formats cannot represent such duplicity.
459+
460+
I<the existing guesswork> remains because as well as dualvars, values might
461+
be C<undef>, references, overloaded references, typeglobs and other things that
462+
Perl itself can represent but do not map one-to-one into external formats, so
463+
need some amount of approximation or encapsulation.
352464

353465
=back
354466

t/porting/known_pod_issues.dat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ pod/perlandroid.pod Verbatim line length including indents exceeds 78 by 3
388388
pod/perlbook.pod Verbatim line length including indents exceeds 78 by 1
389389
pod/perldebguts.pod Verbatim line length including indents exceeds 78 by 24
390390
pod/perldebtut.pod Verbatim line length including indents exceeds 78 by 2
391+
pod/perldelta.pod line containing nothing but whitespace in paragraph 6
391392
pod/perldtrace.pod Verbatim line length including indents exceeds 78 by 7
392393
pod/perlgit.pod ? Should you be using F<...> or maybe L<...> instead of 3
393394
pod/perlgit.pod Verbatim line length including indents exceeds 78 by 1

0 commit comments

Comments
 (0)