Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

RFC: Devel::Deprecate

by Ovid (Cardinal)
on Apr 23, 2008 at 16:01 UTC ( [id://682407]=perlmeditation: print w/replies, xml ) Need Help??

Update: the upload announcement.

I'm trying to help with a common problem that many of us encounter. We have a deadline. We need to implement a feature, but we need to deprecate something (or refactor, or rewrite) but we only have the time to implement the feature if we don't do the refactor. We tell ourselves we'll remember, or put it in our Wiki, or write TODO tests, but those are often overlooked. I propose something like this:

package Customer; use Devel::Deprecate 'deprecate'; sub persist { my $self = shift; my $change_event = shift || $self->change_event; deprecate( { reason => 'Should no longer have an optional change event', warn => '2008-06-12', # or DateTime object die => '2008-08-12', # or DateTime object if => ( scalar @_ ), # optional? } ); ... rest of method }

With this, when the warn date occurs, your test suite starts issuing warnings if the code is still there. Warnings will include the 'die' date, the package and line number.

When the 'die' date occurs, it's a fatal error.

Any issues with this approach? I'm ambivalent about the 'if' condition (you could wrap it if you needed to, but why leave dead code?). Any features you think would be worthwhile?

Cheers,
Ovid

New address of my CGI Course.

Replies are listed 'Best First'.
Re: RFC: Devel::Deprecate
by dragonchild (Archbishop) on Apr 23, 2008 at 16:08 UTC
    The if clause should be a subroutine. Otherwise, get it up there!

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: RFC: Devel::Deprecate
by Jenda (Abbot) on Apr 23, 2008 at 22:25 UTC

    I would not want the code that was tested and put to production to start producing warnings or even crashing when not updated by a certain date. For whatever reason the schedule may slip, the new version be postponed and then what? Will you release a quickfix that just changes the dates? And hope you did not forget any or change the computer clock before you run the test to make sure?

    If the Devel::Deprecate knows to only make fuss within the test suite, great, if it's a timebomb within production code, no thanks.

      And hope you did not forget any or change the computer clock before you run the test to make sure?... if it's a timebomb within production code, no thanks.

      Extra thanks for my part. The sort of fuzziness on deadlines is no small part of why things slip. I find real deadlines tremendously important in life and one of the easiest ways to tell apart people I want in my life and people I don't. I died a little inside every time someone at university begged, cajoled, or threatened a professor into extending a deadline. Sidenote: Come to think of it, maybe checking a server clock should be a part of any robust deployment and test suite.

      Being realistic, of course you're right, schedules slip. I think there are at least three ways to approach it.

      1. Don't use the "die" argument. If you're in the kind of company that lets millions of error log lines stack up with warnings without caring, what's another 100,000?
      2. Use named environment constants -- like MILESTONE_3_a => '2008-08-02' -- to set the dates so they may be updated at a single point as the project might require.
      3. Use the callback sub ref to allow deprecated code to still run while in the production environment only.

      For the interface it might be nice to be able to have confess, cluck along with die and warn as args... or hooks for your local exception mechanism...?

      I think the "timebomb" thing is a bad idea at all. It should *warn* that at some time in the future it won't be available, it can even have a prediction of when that is, but I don't think it makes any sense for a software to have a different API depending on the Date.

      I would suggest, however, to replace the Dates for using version numbers, saying that the method is deprecated since version X, and is expected to be removed by version Y, but no automatic disabling of the method.

      daniel
Re: RFC: Devel::Deprecate
by mr_mischief (Monsignor) on Apr 23, 2008 at 16:35 UTC
    This is a nice reminder system with real teeth. It's a good idea as is. If you wanted, you could even generalize this to be a phased update system to introduce changes on a given date as well.

      I thought about an update system, but realized that I'd be introducing a complication that might not be appropriate. Going with dragonchild's recommendation of making the 'if' key point to a subroutine and you could hook in anything you wanted. Suggestions still welcome, though.

      I think possibly that if we hit the 'die' date, maybe it should warn if the condition is not triggered. That way developers would know to remove the code or update their dates.

      Cheers,
      Ovid

      New address of my CGI Course.

        Well, I'm not sure how to name them, but if you had an unlimited number of dates and each date could be assigned its own sub, you could make it extremely flexible. Perhaps an unlimited number, but with certain names reserved would work.

        phased_update( { intro => [ "2008.06.01", sub {} ], # not reserved foo => [ "2008.08.01", sub {} ], # not reserved deprecate => [ "2008.12.31", sub {} ], # reserved dead => [ "2010.01.01", sub {} ], # reserved } );

        The exact syntax might need some work, but you get the idea. The reserved values could trigger default actions if there's no sub.

Re: RFC: Devel::Deprecate
by kyle (Abbot) on Apr 23, 2008 at 18:46 UTC

    I'd want to be able to omit the 'die' date. It's too much like a time bomb for me. I imagine someone writing lots of these and then skipping town before they all go off.

Re: RFC: Devel::Deprecate
by Your Mother (Archbishop) on Apr 23, 2008 at 16:43 UTC

    I'm with dragonchild, sounds fantastic. I already have a nickname for it: "the other coding by contract." It would be nice to have some facility to remind everyone that it should be removed eventually, no? Years after the issue is dead and buried the code might still be running for no reason. Have no idea how to approach that though.

      As mentioned to mr_mischief, I was thinking that (pseudocode):

      if today >= die_date if 'if' is present if 'if' returns true die reason else warn reason # they won't forget it now! endif else die reason # automatically die if no condition endif endif

      Thus, they get deprecation warnings even after the 'die' date, even if no code triggers the deprecation. I'm not sure if this is a good idea or not.

      I'm also thinking about aliases to the deprecation name: deprecation_XXX and deprecation_TODO. Programmers often embed XXX and TODO in their code and grep for them regularly. This will make it easier to find.

      Cheers,
      Ovid

      New address of my CGI Course.

Re: RFC: Devel::Deprecate
by jdporter (Paladin) on Apr 24, 2008 at 12:43 UTC
    I like it. But...
    I'm ambivalent about the 'if' condition

    I'm beyond ambivalent. What would be the advantage of that over

    if ( @_ ) { deprecate( { reason => 'Should no longer have an optional change event', warn => '2008-06-12', # or DateTime object die => '2008-08-12', # or DateTime object } ); }
    why leave dead code?

    I don't see more or less dead code either way.

    I agree with others - This thing should be a no-op except when explicitly enabled, e.g. in development/testing. I think an environment switch, similar to DEBUG, with multiple severity levels, would work.

    A word spoken in Mind will reach its own level, in the objective world, by its own weight

      I think you're right about the 'if' condition. Not sure what I was thinking, though it's now in there and I've already uploaded.

      By default, the deprecate() sub will only run if you're running tests (it checks for the $ENV{HARNESS_ACTIVE} variable). If, for some reason, this variable is true in your code, you can set $ENV{PERL_DEVEL_DEPRECATE_OFF} to a true value to disable the deprecation. Of course, as previously pointed out, merely omitting the 'die' date ensures that no fatal error will occur.

      Cheers,
      Ovid

      New address of my CGI Course.

        I think you're right about the 'if' condition. Not sure what I was thinking, though it's now in there and I've already uploaded.

        Maybe you can... uh, what's the word... remove it from the supported features? :)

        /J

Re: RFC: Devel::Deprecate
by stiller (Friar) on Apr 24, 2008 at 07:06 UTC
    This is a great idea!

    But I don't think this should affect use of the module, -other than during test / install. In production, it should probably be a no-op? So, how to tell that we care? Setting MIND_DEPRECATED?

    This can, and probably will, be used in unfortunate ways otherwise.

Re: RFC: Devel::Deprecate
by redhotpenguin (Deacon) on Apr 24, 2008 at 05:30 UTC

    An environment variable or some configuration means for the dates would be nice. Something so that when that time is eventually hit you can give yourself another chance. Because we all know how those deadlines can strike without warning, right in the middle of a storm

Re: RFC: Devel::Deprecate
by starbolin (Hermit) on Apr 24, 2008 at 20:39 UTC

    I would like to echo the other wet-blankets. This would be a dangerous animal if released into the wilds. There exists forces plenty enough trying to break our code. Programmers need to be proactive in building defenses not in building bombs.

    It seems to be taking a task management problem and pushing out to where it has the potential to be a customer problem.

    deprecate( { reason => 'The world is going to end anyway.', warn => '2038-01-01', # 19 days till end of the world. die => '2038-01-19', # If you reach here you are 64 bit +. } );


    s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s |-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,, $|=1,select$,,$,,$,,1e-1;print;redo}
Re: RFC: Devel::Deprecate
by Anonymous Monk on Apr 25, 2008 at 08:04 UTC
Re: RFC: Devel::Deprecate
by halley (Prior) on Apr 25, 2008 at 16:13 UTC
    I can see that Ovid's approach is more elaborate, especially about the triggering mechanism, but given the discussion about "when is it warranted" I thought I'd link to my earlier discussion of my use deprecated; pragmatic module. There's some good discussion in the thread at use deprecated; which may stand in for this RFC.

    --
    [ e d @ h a l l e y . c c ]

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://682407]
Approved by kyle
Front-paged by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (7)
As of 2024-04-23 08:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found