¿Mejor práctica para marcar código obsoleto en Ruby?
Me gustaría marcar un método como obsoleto, para que las personas que lo usan puedan verificar fácilmente su código y ponerse al día. En Java se establece @Obsoleto y todo el mundo sabe lo que esto significa.
Entonces, ¿hay una forma preferida (o incluso herramientas) de marcar y verificar si hay obsoletas en Ruby?
10 answers
Para casi todos los casos, depender de una biblioteca o metaprogramación para una obsolescencia es exagerado. Simplemente agregue un comentario al rdoc y llame al método Kernel#warn
. Por ejemplo:
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
Si estás usando Yard en lugar de rdoc , tu comentario doc debería tener este aspecto:
# @deprecated Please use {#useful} instead
Por último, si se adhiere a tomdoc , haga que su comentario se vea así:
# Deprecated: Please use `useful` instead
Obsoleto: Indica que el método está obsoleto y se eliminará en una versión futura. Debe usar esto para documentar métodos que eran públicos pero que se eliminarán en la próxima versión principal.
Además, no olvides eliminar el método obsoleto en algún futuro (y correctamente semver'd) release. No cometas los mismos errores que las bibliotecas Java.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-25 21:09:06
Ruby Standard Library tiene un módulo con la lógica de advertencia: http://ruby-doc.org/stdlib-1.9.3/libdoc/rubygems/rdoc/Gem/Deprecate.html. Tiendo a preferirlo para mantener mis mensajes en desuso de una manera "estándar":
# my_file.rb
class MyFile
extend Gem::Deprecate
def no_more
close
end
deprecate :no_more, :close, 2015, 5
def close
# new logic here
end
end
MyFile.new.no_more
# => NOTE: MyFile#no_more is deprecated; use close instead. It will be removed on or after 2015-05-01.
# => MyFile#no_more called from my_file.rb:16.
Tenga en cuenta que con este enfoque obtendrá información gratuita sobre dónde se llevó a cabo la llamada.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-14 21:37:52
Si quieres ser malo (bajo la astucia de ser útil) puedes imprimir la primera línea de la pila de llamadas durante una advertencia para que los desarrolladores sepan dónde están usando una llamada obsoleta.
Esto es malo porque Estoy bastante seguro de que es un éxito de rendimiento.
warn Kernel.caller.first + " whatever deprecation message here"
Cuando se usa correctamente, esto incluirá la ruta absoluta al archivo y la línea donde se usó la llamada obsoleta. Más información sobre Kernel::caller está disponible aquí
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-25 22:29:47
También puede usar ActiveSupport::Deprecation
(disponible en la versión 4.0+), como tal:
require 'active_support/deprecation'
require 'active_support/core_ext/module/deprecation'
class MyGem
def self.deprecator
ActiveSupport::Deprecation.new('2.0', 'MyGem')
end
def old_method
end
def new_method
end
deprecate old_method: :new_method, deprecator: deprecator
end
MyGem.new.old_method
# => DEPRECATION WARNING: old_method is deprecated and will be removed from MyGem 2.0 (use new_method instead). (called from <main> at file.rb:18)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-07 12:30:24
Usando ActiveSupport:
class Player < ActiveRecord::Base
def to_s
ActiveSupport::Deprecation.warn('Use presenter instead')
partner_uid
end
end
Las advertencias están desactivadas en el entorno de producción de forma predeterminada
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-03 09:32:56
Usted tiene libdeprecated-ruby
(2010-2012, ya no está disponible en rubygem en 2015)
Una pequeña biblioteca destinada a ayudar a los desarrolladores que trabajan con código obsoleto.
La idea proviene del lenguaje de programación' D
', donde los desarrolladores pueden marcar cierto código como obsoleto, y luego permitir/rechazar la capacidad de ejecutar código obsoleto.
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-01 06:01:31
Puedes usar el patrón de Macros de clase y escribir algo como esto:
class Module
def deprecate(old_method, new_method)
define_method(old_method) do |*args, &block|
warn "Method #{old_method}() depricated. Use #{new_method}() instead"
send(new_method, *args, &block)
end
end
end
class Test
def my_new_method
p "My method"
end
deprecate :my_old_method, :my_method
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-07 06:47:43
Al usar rails, tiene el método Module#deprecate.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-07 11:34:39
Canivete es una gema que le permite desaprobar sus métodos de manera simple y elegante. Un poco más sobre esto aquí .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-01 11:50:05
Terminé lanzando juntos un método ligero:
def deprecate(msg)
method = caller_locations(1, 1).first.label
source = caller(2, 1).first
warn "#{method} is deprecated: #{msg}\ncalled at #{source}"
end
Luego, para desaprobar un método, inserte una llamada en el cuerpo del método (o un constructor para una clase)
def foo
deprecate 'prefer bar, will be removed in version 3'
...
end
Es bastante declarativo y proporciona registro con información relevante. No soy mucho de un Rubyist así que puede necesitar algunos ajustes / YMMV.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-15 00:46:23