develooper Front page | perl.perl5.porters | Postings from September 2011

For Jesse: What is the desired behavior of UNIVERSAL::VERSION(Related to perl #95544)

Thread Next
David Golden
September 25, 2011 20:03
For Jesse: What is the desired behavior of UNIVERSAL::VERSION(Related to perl #95544)
Message ID:

There have been some ongoing discussions about the proper behavior of
UNIVERSAL::VERSION.  I think we're at the point where those closest to
the issue agree to disagree and we need a ruling from the chair.  I
hope I can summarize the issue quickly and fairly.  :-)

Context:  Without argument, Foo->UNIVERSAL::VERSION returns something
related to $Foo::VERSION.  Consider this case:

    package Foo;
    our $version = v1.2.3;

Until Perl v5.10, Foo->VERSION returned $Foo::VERSION exactly.  E.g.
for v5.8.1 (which keeps v-string magic) to v5.8.9, you get this:

SV = PVMG(0x250e918) at 0x24c83a0
  REFCNT = 1
  IV = 0
  NV = 0
  PV = 0x24e5030 "\1\2\3"\0
  CUR = 3
  LEN = 4
  MAGIC = 0x24e1840
    MG_VIRTUAL = 0
    MG_TYPE = PERL_MAGIC_v-string(V)
    MG_LEN = 6
    MG_PTR = 0x24d27a0 "v1.2.3"

(Perl v5.6.0-v5.8.0 would give you the same thing without the MAGIC, I believe.)

Starting with v5.10, Foo->VERSION returned the stringified form of a
version object created from $Foo::VERSION.  E.g.

SV = PV(0x998158) at 0x9b97c0
  REFCNT = 1
  PV = 0x9c3dc0 "v1.2.3"\0
  CUR = 6
  LEN = 8

For reference, the documentation of UNIVERSAL::VERSION corresponds to
the pre-v5.10 behavior:

    "VERSION" will return the value of the variable $VERSION in the
    package the object is blessed into.

The v5.10 UNIVERSAL::VERSION behavior causes problems as of v5.14 when
version->new($Foo::VERSION) dies if $Foo::VERSION does not pass the
"lax" version number check.  (Previously, it would warn and discard
invalid input.)  An example of an invalid version would be
$Foo::VERSION="3alpha".  Commit 9bf41c1 changed UNIVERSAL::VERSION to
the pre-v5.10 behavior, but there are open questions about whether
this is desirable or not that I think only the pumpking can resolve.

In short, we need to decide the desired "v5.16" behavior of UNIVERSAL::VERSION.

(a) returns $Foo::VERSION unmodified
(b) returns stringified form of version->new($Foo::VERSION) [possibly
dying on invalid input under newer]
(c) some other behavior

Once that question is resolved, if there is a behavior change, we need
to decide how to implement this in a way that is least disruptive to
users of v5.16 and legacy versions of Perl, particularly given the
prior, existing v5.10 behavior change and the various CPAN releases of live in the wild.  (I.e. we need to determine how a new installed on an older Perl should work.)  Possible
variations could include (not all mutually exclusive)

(i) new behavior with/without "use v5.16"
(ii) implements same/different behavior under different Perl versions

I think we can bikeshed this latter question once the desired behavior
question is resolved.

The "easiest" solution is to revert 9bf41c1 and stick with the v5.10
behavior (but document it correctly), though with the risk that
"invalid" versions will break as of v5.14+.  Should we consider that a
regression?  Should we just 'grandfather' them in somehow?  (Return
stringified version object *or* original $Foo::VERSION if object can't
be created?)

Jesse, apologies for the long email, but please pick a direction and
then we'll get on with implementing a least-worst solution.  :-)

-- David

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About