Лучшая практика помечать устаревший код в Ruby?

Я бы хотел пометить метод как устаревший, чтобы люди, использующие его, могли легко проверить свой код и наверстать упущенное. В Java вы устанавливаете @Deprecated, и все знают, что это значит.

Так есть ли предпочтительный способ (или даже инструменты), чтобы помечать и проверять устаревание в Ruby?

119 голосов | спросил blindgaenger 16 72008vEurope/Moscow11bEurope/MoscowSun, 16 Nov 2008 18:20:13 +0300 2008, 18:20:13

10 ответов


0

Практически во всех случаях в зависимости от библиотеки или метапрограммирования устаревание является излишним. Просто добавьте комментарий к rdoc и вызовите метод Kernel#warn. Например:

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

Если вы используете ярд вместо rdoc , ваш комментарий к документу должен выглядеть следующим образом:

# @deprecated Please use {#useful} instead

Наконец, если вы придерживаетесь tomdoc , сделайте так, чтобы ваш комментарий выглядел следующим образом:

# Deprecated: Please use `useful` instead
  

Устаревший. Указывает, что метод устарел и будет удален в следующей версии. Вы ДОЛЖНЫ использовать это для документирования методов, которые были Public, но будут удалены в следующей основной версии.


Кроме того, не забудьте удалить устаревший метод в будущем (и правильно semver 'd ) релиз . Не допускайте тех же ошибок, что и библиотеки Java.

ответил Ryan McGeary 16 72008vEurope/Moscow11bEurope/MoscowSun, 16 Nov 2008 20:09:44 +0300 2008, 20:09:44
0

Стандартная библиотека Ruby содержит модуль с логикой предупреждения: http://ruby-doc.org/stdlib-1.9.3/libdoc/rubygems/rdoc/Gem/Deprecate.html . Я предпочитаю, чтобы он поддерживал мои сообщения об устаревании "стандартным" способом:

# 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.

Обратите внимание, что при таком подходе вы получите бесплатную информацию о том, где произошел звонок.

ответил Ricardo Valeriano 9 Mayam14 2014, 04:11:58
0

Если вы хотите иметь в виду (под лозунгом полезности), вы можете распечатать первую строку callstack во время предупреждения, чтобы сообщить разработчикам, где они используют устаревший вызов.

Это подло, потому что я уверен, что это удар по производительности.

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

При правильном использовании это будет включать абсолютный путь к файлу и строку, где использовался устаревший вызов. Дополнительную информацию о Kernel :: caller можно получить здесь

ответил Adam French 26 Mayam10 2010, 02:29:47
0

Использование ActiveSupport:

class Player < ActiveRecord::Base
  def to_s
    ActiveSupport::Deprecation.warn('Use presenter instead')
    partner_uid
  end
end

Предупреждения по умолчанию отключены в производственной среде

ответил Artur Beljajev 3 PM000000120000005631 2016, 12:32:56
0

Вы также можете использовать ActiveSupport::Deprecation (доступно в версии 4.0+), как таковое:

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)
ответил Kris 27 J0000006Europe/Moscow 2013, 13:42:28
0

У вас есть libdeprecated-ruby (2010-2012, больше не доступно на rubygem в 2015 году)

Небольшая библиотека, предназначенная для помощи разработчикам, работающим с устаревшим кодом.
Идея исходит из языка программирования D, где разработчики могут пометить определенный код как устаревший, а затем разрешить /запретить возможность выполнения устаревший код.

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 16 72008vEurope/Moscow11bEurope/MoscowSun, 16 Nov 2008 18:31:12 +0300 2008, 18:31:12
0

Вы можете использовать шаблон Class Macros и написать что-то вроде этого:

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
ответил Alex Djioev 7 FebruaryEurope/MoscowbTue, 07 Feb 2012 10:47:43 +0400000000amTue, 07 Feb 2012 10:47:43 +040012 2012, 10:47:43
0

При использовании rails у вас есть метод Module # deprecate.

ответил Pedro Morte Rolo 7 FebruaryEurope/MoscowbTue, 07 Feb 2012 15:34:39 +0400000000pmTue, 07 Feb 2012 15:34:39 +040012 2012, 15:34:39
0

Canivete - это драгоценный камень, который позволяет вам отказаться от ваших методов простым и элегантным способом. Еще немного об этом здесь .

ответил skalee 1 PM00000030000000531 2010, 15:50:05
0

Я закончил тем, что бросил вместе легкий метод:

def deprecate(msg)
  method = caller_locations(1, 1).first.label
  source = caller(2, 1).first
  warn "#{method} is deprecated: #{msg}\ncalled at #{source}"
end

Затем, чтобы отказаться от метода, вставьте вызов в тело метода (или конструктор для класса)

def foo
  deprecate 'prefer bar, will be removed in version 3'
  ...
end

Это довольно декларативно и обеспечивает регистрацию с соответствующей информацией. Я не очень разбираюсь в Rubyist, так что может понадобиться немного подправить /YMMV.

ответил Matt Whipple 15 J0000006Europe/Moscow 2016, 03:46:23

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132