I am trying to fix XS CPAN mod that is atleast a decade old. I read Planning for Backwards Compatibility. The C docs I refer to are the docs on the C API that this CPAN mod wraps. They are not written by the person who wrote the CPAN mod. When I contact the current maintainer of the CPAN the maintainer mentioned they dont have a copy of the C library (its closed source) and said to keep backwards compatibility, and the original author who also doesn't have a copy of the C library anymore didn't mention backwards compatibility and suggested that trying to sync the Perl side of the module to the C docs is not necessary in his opinion. The module API has various problems such None of these are show stopper bugs from using the module, and I'm pretty sure everyone who used the module over the last 10 years has placed workarounds in their code for these quirks. I did atleast. Now how to fix this mess. None of the fixes are new features or new method calls, but they break backwards compatibility with all existing code. How does someone go about fixing a CPAN library like this?

Currently I wrote a VERSION and import() sub to deal with the case of "use Local::Foo 'importme';", "use Local::Foo 3.05 'importme' ;" and "use 3.05 Local::Foo '3.05' 'importme';" with calls Exporter and UNIVERSAL with "shift->SUPER::VERSION(@_);" and "shift->SUPER::import(@_);". In the VERSION and import subs I wrote, a const sub is evaled, something like this
if($_[0] >= 3.05){ eval "sub USE_NEWAPI () { 1 }"; } else{ eval "sub USE_NEWAPI () { 0 }"; }
In the methods for this module, the USE_NEWAPI is called and the perl optimizer constant folds away conditional branches to either behavior of the old API or the new API (checked with B::Deparse). The module's test files were updated to reflect old api and new api behavior and make sure old way of doing things still works. Some games with require and another PM file are used to create a 2nd compiling context for the new or old api affected methods to allow the constant folder to work. The only problem with this design is, what if the CPAN downloader, in his script does
use Local::Foo::Parser; use Local::Foo 3.08;
internally Local::Foo::Parser does
use Local::Foo;
The module Local::Foo::Parser is a separate CPAN library, and there are about half a dozen CPAN libraries that use Local::Foo, bugs and all. I think what will happen is, the CPAN download will not get the new API, because Local::Foo was "use"d with the "old" buggy api in a different mod. If the order of the CPAN downloader's use statements are reversed, Local::Foo::Parser will develop a ton of bugs because of the API changes that Local::API suddenly has.

So I ask, how is this supposed to be fixed?

caller checks to see if its main:: or not in Local::Foo?

a localized "$Local::Foo::newapi = 1;" (does local work this way)?

Who cares about Local::Foo::Parser, I'm not bug fixing it, and they should keep up with module they use internally! its their fault not threatening to do a CPAN unauthorized release 7 years ago when their RT bug report and their patch for the bug were filed and then after not getting a response in a couple days they decided to put work arounds in Local::Foo::Parser that have been there 7 years and counting.

Or forking the Local::Foo class is the only way to fix this mess? create a PM file in Local::Foo's tarball called "Local::Foo::______" and @ISA inherit the methods that aren't buggy or dependent on newapi or oldapi behavior from Local::Foo. Maybe put buggy methods in a PM file called Local::Foo::OldMethods.pm and require them on demand if someone calls Local::Foo::new()?

Where does the POD for Local::Foo::______ go? in a new POD document in Local::Foo::______ or add sections "With ::______ methodname does XXXXXX" in the section of Local::Foo where methodname is documented? What should _______ be? if its the word "new" it wont be "new" 10 years from now, so thats dumb. Plus "$obj = new Local::Foo::new("parameter 1");" looks funny.

Or screw backwards compatibility, fix the existing method calls and you a cpan downloader should never upgrade a CPAN mod unless you've performed due diligence by read the POD and changes file on it first and then tested your existing code and and indirectly other existing CPAN modules you use (which may or may not use the mod your using internally). The old tarball is still on cpan.org for anyone who wants it.

Change the existing buggy methods to a croak("MethodName has been removed as of version 3.05 of Local::Foo") and make a sub called MethodNameV3?

I'd like to keep the discussion abstract rather than mention the specific CPAN library and then get answers specific to that CPAN library that don't apply to anything else in the perl world.

In reply to CPAN module versioning/backwards compatibility by bulk88

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.