Pergunta

Eu gostaria de marcar um método como obsoleto, por isso as pessoas que usam ele pode facilmente verificar o seu código e apanhar. Em Java você definir @deprecated e todo mundo sabe o que isso significa.

Então, há uma maneira preferida (ou até mesmo ferramentas) para marcar e verificar se há reprovações em Ruby?

Foi útil?

Solução

Para quase todos os casos, dependendo de uma biblioteca ou metaprogramming para uma depreciação é um exagero. Basta adicionar um comentário ao rdoc e chamar o método Kernel#warn. Por exemplo:

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

Se você estiver usando Quintal em vez de rdoc , o seu comentário doc deve ficar assim:

# @deprecated Please use {#useful} instead

Por último, se você aderir a tomdoc , o seu comentário parecido com este:

# Deprecated: Please use `useful` instead

Deprecated: Indica que o método é obsoleto e será removido em uma versão futura. Você deve usar isso para métodos de documentos que eram públicos, mas serão removidas na próxima versão principal.


Além disso, não se esqueça de remover o método obsoleto em algum futuro (e devidamente semver 'd ) liberação . Não cometer os mesmos erros que as bibliotecas Java fez.

Outras dicas

Biblioteca Padrão Ruby tem um módulo com a lógica aviso: http://ruby-doc.org/stdlib-1.9.3/libdoc/rubygems/rdoc/Gem/Deprecate.html . I tendem a preferir-lo a manter as minhas mensagens de descontinuação de uma forma "padrão":

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

Note que, com essa abordagem, você vai ganhar gratuitamente informações sobre onde a chamada ocorreu.

Se você quer ser média (sob o engano de ser útil) você pode imprimir a primeira linha da pilha de chamadas durante um aviso para deixar devs saber onde eles estão usando uma chamada obsoleta.

Esta é média porque eu tenho certeza que é um desempenho de sucesso.

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

Quando usado corretamente, isso vai incluir o caminho absoluto para o arquivo e linha onde a chamada obsoleta foi usado. Mais informações sobre Kernel :: chamador está disponível aqui

Usando ActiveSupport:

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

Os avisos são desligadas em ambiente de produção por padrão

Você também pode usar ActiveSupport::Deprecation (disponível na versão 4.0+), tais como:

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)

Você tem libdeprecated-ruby (2010-2012, não está mais disponível no rubygem em 2015)

Uma pequena biblioteca destina a ajudar os desenvolvedores que trabalham com código obsoleto.
A idéia vem do 'D' linguagem de programação, onde os desenvolvedores podem marcar determinado código como obsoleto, e em seguida, permitir / não permitir a capacidade de executar 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

Você pode usar o padrão Classe Macros e escrever algo como isto:

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

Ao usar rails, você tem o método # deprecate Module.

Canivete é uma jóia que permite depreciar seus métodos de maneira simples e elegante. Um pouco mais sobre ele aqui .

acabei jogando juntos um método leve:

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

Em seguida, a deprecate um método de inserção de uma chamada no corpo do método (ou um construtor de uma classe)

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

É bastante declarativa e fornece log com informações relevantes. Eu não sou muito de um Rubyist por isso pode precisar de alguns ajustes / YMMV.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top