Following the discussion in Why eval $version? I'd like to propose the following approach.

Usage

use Version::Easy; $VERSION = 'v1.2.3'; # v-str # or... $VERSION = '1.002003'; # float $VERSION = 'v1.2.3_4'; # v-str + alpha $VERSION = '1.002003_4'; # float + alpha

please note that:

Implementation:

Doesn't this solve most (or all) problems???

Please comment! Where does this fail? :)

use strict; use warnings; # -------------------------------------------------- package Version::Easy; use Data::Dump qw/pp dd/; use version; sub import { my $pkg = (caller)[0]; my $version; tie $version, 'Version::Easy::Tie'; no strict 'refs'; *{${pkg}."::VERSION"} = \$version; } # -------------------------------------------------- package Version::Easy::Tie; require Tie::Scalar; our @ISA = qw(Tie::StdScalar); use version qw/is_lax/; sub STORE { my ($self,$value)= @_; warn "IN:\t\t",$value; if ( is_lax($value) ) { $$self = version->parse($value); } else { warn "corrupt VERSION format $value"; } } # BUG? perldoc Tie::Scalar says no TIESCALAR needed sub TIESCALAR { my $class = shift; my $version; return bless \$version, $class; } 1; # -------------------------------------------------- # --- fake already required for 'use' demo BEGIN { $INC{'Version/Easy.pm'} = 1; } # -------------------------------------------------- # # DEMO # # package TST; use Version::Easy; # --------- test v-str $VERSION = 'v1.2.3'; warn "Str:\t" ,$VERSION; warn "Float:\t" ,$VERSION->numify; warn "V-str:\t" ,$VERSION->normal; my $v1 = $VERSION; # --------- test float $VERSION = '1.002003'; warn "Str:\t" ,$VERSION; warn "Float:\t" ,$VERSION->numify; warn "V-str:\t" ,$VERSION->normal; my $v2 = $VERSION; warn "Are both Version equal?:", $v1 == $v2; warn "v-str bigger?:", $v1 > 'v1.2.2'; warn "v-str smaller?:", $v1 < 'v1.2.4'; warn "v-str not smaller?:", $v1 < 'v1.2.2'; # # --------------------------------------------------

-*- mode: compilation; default-directory: "d:/exp/" -*- Compilation started at Fri Jul 10 19:13:58 C:/Perl_524/bin\perl.exe d:/exp/Version_Easy.pl IN: v1.2.3 at d:/exp/Version_Easy.pl line 29. Str: v1.2.3 at d:/exp/Version_Easy.pl line 69. Float: 1.002003 at d:/exp/Version_Easy.pl line 70. V-str: v1.2.3 at d:/exp/Version_Easy.pl line 71. IN: 1.002003 at d:/exp/Version_Easy.pl line 29. Str: 1.002003 at d:/exp/Version_Easy.pl line 78. Float: 1.002003 at d:/exp/Version_Easy.pl line 79. V-str: v1.2.3 at d:/exp/Version_Easy.pl line 80. Are both Version equal?:1 at d:/exp/Version_Easy.pl line 84. v-str bigger?:1 at d:/exp/Version_Easy.pl line 86. v-str smaller?:1 at d:/exp/Version_Easy.pl line 87. v-str not smaller?: at d:/exp/Version_Easy.pl line 88. Compilation finished at Fri Jul 10 19:13:58

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re: RFC: Version::Easy
by tobyink (Canon) on Jul 12, 2020 at 07:08 UTC
      Good point! Thanks :)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      PS: this was my 8888 th post so far :)

Re: RFC: Version::Easy
by Haarg (Priest) on Jul 13, 2020 at 11:17 UTC

    You should probably clarify what problems you are actually trying to solve with this approach. The 'Why eval $version?' post is a long thread discussing a variety of issues. Most of the issues regarding version comparisons are handled by perl 5.10. And this doesn't help with the original question proposed in the 'Why eval $version?' post, which was regarding a version extracted by ExtUtils::MakeMaker.

      > You should probably clarify what problems you are actually trying to solve with this approach.

      avoiding boilerplates.

      > The Why eval $version? post is a long thread discussing a variety of issues.

      Indeed, but if there are problems left, they could be solved inside the module.

      > which was regarding a version extracted by ExtUtils::MakeMaker.

      I don't understand, could you please elaborate?

      edit

      "version" like version.pm or like $VERSION?

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        This module would replace the boilerplate of $VERSION =~ tr/_//d; with the new boilerplate of use Version::Easy;. This doesn't seem like a significant improvement, and adds several dependencies. use version; already accomplishes basically the same thing as this module.

        The original question was about a test that was extracting a version number using MM->parse_version. Any tool doing "static" version extraction isn't aided by a module like Version::Easy.

Re: RFC: Version::Easy
by jcb (Parson) on Jul 12, 2020 at 03:45 UTC

    This is an interesting little bundle of magic, but is use version; our $VERSION = version->declare('VERSION_GOES_HERE'); really that hard to write?

    Similarly, maybe this should go one step farther and accept the version as an argument to import? Then users could write:

    use Version::Easy 'v1.2.3';

    This would abstract the magic $VERSION variable away into an implementation detail.

      use Version::Easy 'v1.2.3';

      This has the disadvantage that static parsers like the PAUSE indexer won't be able to find the version.

      Like I already said and Toby explained, backwards compatibility to static parsers is a crucial issue here, and

      version->declare('VERSION_GOES_HERE')

      would become just another tribal knowledge.

      You'll find $VERSION also documented in hundreds of places, fixing old documentation is one of Perl's biggest mortgages.

      Furthermore could "Version::Easy" be easily bundled into one master module to rule ehm use them all, hence simplifying boilerplates.

      Compare Modern::Perl.

      Of course a built-in feature

      vers v1.2.3;

      might be more elegant, but this could easily be introduced later on top of this semantics once the tool chain is modernized.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        There's already a built-in version syntax from Perl 5.14 onwards.

        package Foo::Bar 1.23; ...; # or package Foo::Bar 1.23 { ...; }

        And the PAUSE indexer, etc supports it. It's only a problem if you need to support Perl versions earlier than 5.14.