Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mark a class as Deprecated in Ruby?

In Ruby (and even more so: Rails) it is easy to mark methods as deprecated.

But how can I mark an entire class as deprecated? I want to raise a warning whenever a class is used:

class BillingMethod
end

BillingMethod.new #=> DEPRECATION WARNING: the class BillingMethod is deprecated. Use PaymentMethod instead.

Or when it gets used in inheritance:

class Sofort < BillingMethod
end

Sofort.new #=> DEPRECATION WARNING: the class BillingMethod is deprecated. Use PaymentMethod instead. 

Or, when used in nested classes:

class BillingMethod::Sofort < BillingMethod
end

BillingMethod::Sofort.new #=> DEPRECATION WARNING: the class BillingMethod is deprecated. Use PaymentMethod instead. 

I would think that a class_eval-block would be the place where to stick such a warning. Is that the correct place? Or are there better methods?

like image 621
berkes Avatar asked Apr 17 '15 09:04

berkes


2 Answers

You may want to have a look at Deprecate which is part of Ruby's Standard Library:

require 'rubygems'

class BillingMethod
  extend Gem::Deprecate

  class << self
    deprecate :new, "PaymentMethod.new", 2016, 4
  end

  # Will be removed April 2016, use `PaymentMethod.new` instead
  def initialize 
    #...
  end
end

Using the deprecated method would result in a warning like this:

BillingMethod.new
# => NOTE: BillingMethod#new is deprecated; use PaymentMethod.new instead. It will be removed on or after 2016-04-01.
# => BillingMethod#new called from file_name.rb:32.
like image 130
spickermann Avatar answered Oct 20 '22 15:10

spickermann


You can use const_missing to deprecate constants, and, by extension, classes.

const_missing is being invoked when an undefined constant is referenced.

module MyModule

  class PaymentMethod
    # ...
  end

  def self.const_missing(const_name)
    super unless const_name == :BillingMethod
    warn "DEPRECATION WARNING: the class MyModule::BillingMethod is deprecated. Use MyModule::PaymentMethod instead."
    PaymentMethod
  end
end

This allows existing code that references MyModule::BillingMethod to continue to work, and warns the user about their use of the deprecated class.

It's the best I've seen so far for the deprecating class purpose.

like image 45
Andrey Deineko Avatar answered Oct 20 '22 15:10

Andrey Deineko