develooper Front page | perl.perl5.porters | Postings from August 2016

Re: [perl #128786] making $^V a version object broke functionality

Thread Previous | Thread Next
From:
John Peacock
Date:
August 3, 2016 10:40
Subject:
Re: [perl #128786] making $^V a version object broke functionality
Message ID:
73abafde-d342-1641-d7ac-e20a50438739@havurah-software.org
On 07/31/2016 03:46 PM, Lukas Mai wrote:
> Am 31.07.2016 um 17:48 schrieb John Peacock:
>> So your code could be rewritten as:
>>
>>    printf "use feature ':%d.$d;\n", @{$^V->{version}}[0,1];
>
> That's not part of the public API. I'd have to rely on implementation
> details that might change at any time.

Actually, the internal representation *is* part of the public API, see 
version::Internals.  The version.pm code is also specifically designed 
to be easy to subclass, so you would be free to implement your own 
method calls to do whatever you want (like generating a v-string form).

> 1. v-strings are normal scalars: they're strings.

I beg to differ.  v-strings are stored as simple scalar but they are an 
array of code points, usually consisting of what would be non-printable 
control characters.  For example, the current Perl release is

	ENQ CAN NUL

You cannot print a v-string without the special "%vd" format, which 
presupposes that you actually know you have a v-string in the first 
place.  Originally, v-strings were a lossy parsing artifact, with no way 
of distinguishing 53.56.48 from "5.8.0".  After Perl v5.8.1 was 
released, v-strings became a magical type, so you with introspection you 
could distinguish them from normal strings:

$ perl -MDevel::Peek -E 'say Dump(53.56.48)'
SV = PVMG(0x13b0b50) at 0x1366eb8
   REFCNT = 1
   FLAGS = (RMG,POK,READONLY,IsCOW,pPOK)
   IV = 0
   NV = 0
   PV = 0x136bd10 "580"\0
   CUR = 3
   LEN = 10
   COW_REFCNT = 0
   MAGIC = 0x137e8e0
     MG_VIRTUAL = 0
     MG_TYPE = PERL_MAGIC_vstring(V)
     MG_LEN = 8
     MG_PTR = 0x136a740 "53.56.48"


> 2. No special treatment is required for comparing v-strings. v-string
> comparison is normal string comparison.

While this is true, it is also misleading, in that you had to already 
know you were dealing with a v-string to construct your test.  Most 
people found this confusing and used $] instead, which has its own set 
of problems.

> 3. Special treatment is required for comparing version objects. version
> object comparison is not normal string comparison, and inadvertently
> stringifying a version object and then comparing it leads to wrong results.

Then frankly you are using the version module wrong.  A version object 
can be trivially compared against either a 
string-that-looks-like-a-version, a bare number, or another 
version-derived object using either numeric or string comparison 
operators (> and gt).  If you force stringification, of course you lose 
the object methods.

> 4. Pretty-printing a version number is rare in my code. Most of the time
> I only want to compare versions, extract components, and construct new
> versions (e.g. for automatically incrementing a version number, etc).

The fact that the normal stringification method of version objects is to 
print in a consistent normal form is just gravy.  The real reason they 
exist in the first place is to treat versions as first class objects, 
with consistent behavior.  To be honest, you are the first person to 
request being able extract the elements of the version for further 
processing.  Most people appear to want to treat versions as fixed values.

> In that case a method to return the numeric components would be nice, as
> well as a method to get the v-string representation:
>
>     my @parts = $^V->parts;    # (5, 24, 0)
>     my $str   = $^V->vstring;  # "\x05\x18\x00"
>
> Would that be good addition to the version.pm API?

Attached is a proposed addition to the public API that provides the 
elements() method to return the array ref, as well as helper functions 
to print out the epoch/major/minor/patch for any given version object 
(including $^V).  Since this has to replace the internal Perl 
implementation of version.pm with the additional methods, you would have 
to include

   use version;

before you can use any of these methods.  If this would fit your needs, 
I'd be happy to release a new version.pm to CPAN and this functionality 
would be included in any new Perl releases.

John

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About