Chciałbym oznaczyć metodę jako przestarzałą, aby osoby jej używające mogły łatwo sprawdzić swój kod i nadrobić zaległości. W Javie ustawiasz @Deprecated i wszyscy wiedzą, co to oznacza.
Czy jest więc preferowany sposób (a nawet narzędzia) zaznaczania i sprawdzania przestarzałych elementów w Rubim?
ruby
deprecated
blindgaenger
źródło
źródło
Odpowiedzi:
W prawie wszystkich przypadkach, zależność od biblioteki lub metaprogramowania dla wycofania jest przesadą. Po prostu dodaj komentarz do rdoc i wywołaj
Kernel#warn
metodę. Na przykład: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
Jeśli używasz Yard zamiast rdoc , Twój komentarz do dokumentu powinien wyglądać następująco:
# @deprecated Please use {#useful} instead
Na koniec, jeśli zastosujesz się do tomdoc , spraw , aby Twój komentarz wyglądał następująco:
# Deprecated: Please use `useful` instead
Ponadto, nie zapomnij usunąć przestarzałej metody w jakiejś przyszłości (i właściwie semver „d) rozwiązanie . Nie popełniaj tych samych błędów, które popełniały biblioteki Java.
źródło
Ruby Standard Library ma moduł z logiką ostrzegawczą: https://ruby-doc.org/stdlib/libdoc/rubygems/rdoc/Gem/Deprecate.html . Wolę utrzymywać wiadomości o wycofaniu w „standardowy” sposób:
# 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.
Zwróć uwagę, że dzięki takiemu podejściu uzyskasz bezpłatne informacje o tym, gdzie odbyło się połączenie.
źródło
0
w literale numerycznym powoduje, że jest on ósemkowy, więc prawdopodobnie powinien zostać usunięty.deprecate :initialize, UseThisClassInstead, 2017, 5
Jeśli chcesz być wredny (pod pretekstem bycia pomocnym), możesz wydrukować pierwszą linię stosu wywołań podczas ostrzeżenia, aby poinformować programistów, gdzie używają przestarzałego wywołania.
To znaczy, ponieważ jestem prawie pewien, że to hit wydajnościowy.
warn Kernel.caller.first + " whatever deprecation message here"
Jeśli jest używany poprawnie, będzie zawierał bezwzględną ścieżkę do pliku i wiersz, w którym użyto przestarzałego wywołania. Więcej informacji o Kernel :: caller jest dostępnych tutaj
źródło
Korzystanie z ActiveSupport:
class Player < ActiveRecord::Base def to_s ActiveSupport::Deprecation.warn('Use presenter instead') partner_uid end end
Ostrzeżenia są domyślnie wyłączone w środowisku produkcyjnym
źródło
Możesz także użyć
ActiveSupport::Deprecation
(dostępne w wersji 4.0+), jako takich: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)
źródło
Masz
libdeprecated-ruby
(2010-2012, już niedostępny na rubygem w 2015)Mała biblioteka mająca na celu pomóc programistom w pracy z przestarzałym kodem.
Pomysł pochodzi z
D
języka programowania „ ”, w którym programiści mogą oznaczyć określony kod jako przestarzały, a następnie zezwolić / zabronić wykonywania przestarzałego kodu.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
źródło
Możesz użyć wzorca Class Macros i napisać coś takiego:
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
źródło
Używając railsów, masz metodę Module # deprecate.
źródło
Canivete to perełka, która pozwala w prosty i elegancki sposób zdeprecjonować swoje metody. Trochę więcej na ten temat tutaj .
źródło
Skończyło się na połączeniu lekkiej metody:
def deprecate(msg) method = caller_locations(1, 1).first.label source = caller(2, 1).first warn "#{method} is deprecated: #{msg}\ncalled at #{source}" end
Następnie, aby zrezygnować z metody, wstaw wywołanie do treści metody (lub konstruktora dla klasy)
def foo deprecate 'prefer bar, will be removed in version 3' ... end
Jest dość deklaratywny i zapewnia logowanie z odpowiednimi informacjami. Nie jestem zbyt Rubyistą, więc może wymagać pewnych poprawek / YMMV.
źródło
Możemy użyć wewnętrznych metod makr. Przykład:
class Foo def get_a; puts "I'm an A" end def get_b; puts "I'm an B" end def get_c; puts "I'm an C" end
def self.deprecate(old_method, new_method) define_method(old_method) do |*args, &block| puts "Warning: #{old_method} is deprecated! Use #{new_method} instead" send(new_method, *args, &block)
koniec koniec
deprecate: a,: get_a deprecate: b,: get_b deprecate: c,: get_c end
o = Foo.new p oa
źródło