views:

1370

answers:

4

I'd like to mark a method as deprecated, so the people using it can easily check their code and catch up. In Java you set @Deprecated and everybody knows what this means.

So is there a preferred way (or even tools) to mark and check for deprecations in Ruby?

+4  A: 

You do have libdeprecated-ruby

A small library intended to aid developers working with deprecated code.
The idea comes from the 'D' programming language, where developers can mark certain code as deprecated, and then allow/disallow the ability to execute deprecated code.

require 'lib/deprecated.rb'
require 'test/unit'

# this class is used to test the deprecate functionality
class DummyClass
  def monkey
    return true
  end

  deprecate :monkey
end

# we want exceptions for testing here.
Deprecate.set_action(:throw)

class DeprecateTest < Test::Unit::TestCase
  def test_set_action

    assert_raise(DeprecatedError) { raise StandardError.new unless DummyClass.new.monkey }

    Deprecate.set_action(proc { |msg| raise DeprecatedError.new("#{msg} is deprecated.") })

    assert_raise(DeprecatedError) { raise StandardError.new unless DummyClass.new.monkey }


    # set to warn and make sure our return values are getting through.
    Deprecate.set_action(:warn)

    assert_nothing_raised(DeprecatedError) { raise StandardError.new unless DummyClass.new.monkey } 
  end
end
VonC
+17  A: 

For almost all cases, depending on a library or metaprogramming for a deprecation is overkill. Simply add a comment to the rdoc and call the Kernel#warn method. For example:

class Foo
  # <b>DEPRECATED:</b> Please use <tt>useful</tt> instead.
  def useless
    warn "[DEPRECATION] `useless` is deprecated.  Please use `useful` instead."
    useful
  end

  def useful
    # ...
  end
end


If you're using Yard instead of rdoc, your doc comment should look like this:

# @deprecated Please use {#useful} instead


Also, don't forget to remove the deprecated method in some future release. Don't make the same mistakes that the Java libraries did.

Ryan McGeary
I am not sure it is so much a "mistake" from the Java part, rather a huge backward compatibility issue (see http://stackoverflow.com/questions/314540), that blindgaenger might not need to consider for his Ruby code.
VonC
Code is a liability. The less code you have to maintain the better. Deprecations are good for temporary backwards compatibility, but over time it becomes cruft. If people *need* to use retired methods, they should use older versions of your libraries instead.
Ryan McGeary
A: 

If you want to be mean (under the guile of being helpful) you can print out the first line of the callstack during a warning to let devs know where they are using a deprecated call.

This is mean because I'm pretty sure it's a performance-hit.

warn Kernel.caller.first + " whatever deprecation message here"

When used correctly, this will include the absolute path to the file and line where the deprecated call was used. More information about Kernel::caller is available here

Adam French
A: 

Canivete is a gem which enables you to deprecate your methods in simple and elegant way. A little more about it here.

skalee