berkes
berkes

Reputation: 27563

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?

Upvotes: 9

Views: 4041

Answers (3)

spickermann
spickermann

Reputation: 106932

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.

Upvotes: 11

Andrey Deineko
Andrey Deineko

Reputation: 52357

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.

Upvotes: 5

Gena  Shumilkin
Gena Shumilkin

Reputation: 713

Why not do it this way:

def initialize(*args)
  warn "DEPRECATION WARNING: ..."
  super
end

Upvotes: -2

Related Questions