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 19, 2016 20:49
Subject:
Re: [perl #128786] making $^V a version object broke functionality
Message ID:
21e9466f-1e76-0806-a47e-fbc797551e83@havurah-software.org
On 08/03/2016 03:49 PM, Lukas Mai wrote:
> Am 03.08.2016 um 12:39 schrieb John Peacock:
>> 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.
>
> Wait, version::Internals is supposed to be a public API?
>
> You definitely need to document that, then. When something is called
> "internals", I assume it's purely informational and describes a snapshot
> (the current state of the implementation) with no guarantees about
> stability or compatibility.

The version::Internals text originally was part of the main POD and I 
split it out to make the main documentation more applicable for 
consumers of the module.  I originally added the documentation for how 
the object was structured specifically so anyone was free to extend it. 
I realize now that I don't actually say that, so mea culpa.

I actually test the ability to subclass version.pm part of the 
regression suite; I run all tests with the base class and again with a 
trivial subclass.

So here is an example subclass just for you:

-------------------------------------
package vversion;
use base "version";

sub vstring {
      my ($self) = @_;
      my $vs = $self->stringify();
      return eval("$vs");
}

1;
-------------------------------------

Call it like this:

$ perl -I. -Mvversion -MDevel::Peek -E \
    '$v = vversion->new($^V)->vstring(); say Dump($v);'

SV = PVMG(0x15ee440) at 0x1625c68
    REFCNT = 1
    FLAGS = (RMG,POK,IsCOW,pPOK)
    IV = 0
    NV = 0
    PV = 0x1611eb0 "\5\26\1"\0
    CUR = 3
    LEN = 10
    COW_REFCNT = 0
    MAGIC = 0x15f4650
      MG_VIRTUAL = 0
      MG_TYPE = PERL_MAGIC_vstring(V)
      MG_LEN = 7
      MG_PTR = 0x16079e0 "v5.22.1"

That gets you the vstring that you can do anything you want with.  In 
fact, you don't even need to use the subclass; you can just use the same 
technique in your code:

$ perl -MDevel::Peek -E \
    '$v = $^V->stringify; $v = eval("$v"); say Dump($v);'

SV = PVMG(0x247d920) at 0x24b4c68
    REFCNT = 1
    FLAGS = (RMG,POK,pPOK)
    IV = 0
    NV = 0
    PV = 0x2484230 "\5\26\1"\0
    CUR = 3
    LEN = 10
    MAGIC = 0x2498530
      MG_VIRTUAL = 0
      MG_TYPE = PERL_MAGIC_vstring(V)
      MG_LEN = 7
      MG_PTR = 0x24a0f10 "v5.22.1"


Since you seem to be primarily interested in the value of $^V, you can 
skip all of that and go straight to the eval:

$ perl -MDevel::Peek -E    '$v = eval("$^V"); say Dump($v);'
SV = PVMG(0x2308cd0) at 0x22bd210
   REFCNT = 1
   FLAGS = (RMG,POK,IsCOW,pPOK)
   IV = 0
   NV = 0
   PV = 0x2307240 "\5\26\1"\0
   CUR = 3
   LEN = 10
   COW_REFCNT = 0
   MAGIC = 0x22c1fd0
     MG_VIRTUAL = 0
     MG_TYPE = PERL_MAGIC_vstring(V)
     MG_LEN = 7
     MG_PTR = 0x22ae060 "v5.22.1"


All things considered, I think this is not something that absolutely 
requires fixing version.pm or the equivalent core code.

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