Устаревшая имя старого модуля в Ruby? - PullRequest
0 голосов
/ 27 июня 2018

Как мне лучше всего переименовать модуль Ruby обратно совместимым образом? У меня есть ActiveSupport, поэтому я могу вызывать предупреждения об устаревании таким образом, но в этом случае я осуждаю старое имя модуля, а не имена методов.

Пример:

module OldName
  def self.method1
    ...
  end
end

станет:

module NewName
  def self.method1
    ...
  end
end

Я хочу генерировать предупреждения, указывающие разработчику использовать NewName::method1 вместо OldName::method1

Есть предложения?

Ответы [ 5 ]

0 голосов
/ 28 июня 2018

Меня сбила ошибка в патче, который я исправлял, что вызвало несколько фальстартов, но окончательный ответ очень прост, и я включаю рабочий код в качестве примера для других:

require 'active_support'

OldName = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('OldName', 'NewName')

module NewName
  def self.method1
    puts 'Hello World!'
  end
end


NewName.method1
  #=> Hello World!

OldName.method1
  #=> DEPRECATION WARNING: OldName is deprecated! Use NewName instead. (called from ..)
  #=> Hello World!

Simples!

Благодарю @matthewd за то, что он направил меня в правильном направлении.

0 голосов
/ 28 июня 2018
module OldName
  def instance_method(*args)
    yield(args)
  end

  instance_methods.each do |im|
    alias_name = "_#{im.to_s}"
    alias_method alias_name, im
    define_method(im) do |*args, &block|
      warn "Foo is deprecated please use Bar instead"
      public_send(alias_name, *args, &block)
    end
  end
end

class C
  include OldName
end

C.instance_methods && [:im, :_im]
  #=> [:im, :_im]

c = C.new
c._instance_method(2,3) { |a,b| a+b }
  #=> 5
c.instance_method(2,3) { |a,b| a+b }
  # Foo is deprecated please use Bar instead
  #=> 5

В качестве альтернативы public_send(alias_name, *args, &block) можно заменить на method(alias_name).call(*args, &block).

0 голосов
/ 27 июня 2018

Rails 4.1.8 Ruby 2.2.0p0

module Fred
  extend self
  def aaa; end
  def bbb; end
  def ccc; end
  def ddd; end
  def eee; end
end

module Bar
  extend self
  def ccc; end
end


ActiveSupport::Deprecation.deprecate_methods(Fred, :aaa, bbb: :zzz, ccc: 'use Bar#ccc instead')


Fred.aaa
DEPRECATION WARNING: aaa is deprecated and will be removed from Rails 4.2. (called from __pry__ at (pry):15)
=> nil

Тот же код пробовал в рельсах 5.2.0, но не ПРЕДУПРЕЖДЕНИЕ ОБ УСТРОЙСТВЕ .

Rails 5.2.0 Ruby 2.5.1p57

class Fred
 def aaa; end
 def bbb; end
 def ccc; end
 def ddd; end
 def eee; end
end

class Bar
 def ccc; end
end

ActiveSupport::Deprecation.deprecate_methods(Fred, :aaa, bbb: :zzz, ccc: 'use Bar#ccc instead')

> Fred.new.aaa
DEPRECATION WARNING: aaa is deprecated and will be removed from Rails 6.0 (called from irb_binding at (irb):13)
 => nil 
0 голосов
/ 27 июня 2018

Вы можете пойти с чем-то вроде:

module Bar
  def self.aaa
    'Bar::aaa'
  end

  def baz
    'Bar#baz'
  end
end 

module Foo
  {included: :include,extended: :extend,prepended: :prepend}.each do |mod_method, called_method| 
    singleton_class.define_method(mod_method) do |base|
      warn "Foo is deprecated please use Bar instead"
      base.send(called_method,Bar) 
    end
  end
  def self.method_missing(meth,*args,&block)
    warn "Foo is deprecated please use Bar instead"
    Bar.respond_to?(meth) ? Bar.send(meth,*args,&block) : super
  end
end

class A 
  include Foo # this will throw a warning
end

Тогда

Foo.aaa
# Foo is deprecated please use Bar instead
#=> 'Bar::aaa'

A.new.baz  
#=> 'Bar#baz'
0 голосов
/ 27 июня 2018

ActiveSupport предоставляет два способа устаревания константы: DeprecatedConstantAccessor и DeprecatedConstantProxy . У каждого из них есть компромиссы и ограничения в том, когда они показывают предупреждение (Accessor - когда к нему обращаются; Proxy - когда его методы вызываются) и как они обычно ведут себя. Возможно, вы захотите попробовать оба варианта, чтобы увидеть, какой из них подходит для вашего варианта использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...