더 이상 사용되지 않는 코드를 Ruby에 표시하는 가장 좋은 방법은 무엇입니까?


127

메소드를 더 이상 사용하지 않는 것으로 표시하고 싶습니다. 그래서 메소드를 사용하는 사람들은 코드를 쉽게 확인하고 따라 잡을 수 있습니다. Java에서는 @Deprecated를 설정하면 누구나 이것이 무엇을 의미하는지 알고 있습니다.

Ruby에서 더 이상 사용되지 않는 것을 표시하고 확인하는 선호되는 방법 (또는 도구)이 있습니까?


그것은 잠재적 인 교체에 지점에 값이없는 것처럼 공정하게하기 위해, 자바의 주석, 짜증
HEIKO 렆

답변:


160

거의 모든 경우에, 지원 중단에 대한 라이브러리 또는 메타 프로그래밍에 따라 과도하게 사용됩니다. 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 대신 Yard 를 사용하는 경우 문서 주석은 다음과 같아야합니다.

# @deprecated Please use {#useful} instead

마지막으로 tomdoc 을 준수하면 주석을 다음과 같이 만드십시오.

# Deprecated: Please use `useful` instead

더 이상 사용되지 않음 : 메소드가 더 이상 사용되지 않으며 향후 버전에서 제거 될 것임을 나타냅니다. 이것을 사용하여 공개되었지만 다음 주요 버전에서 제거 될 메소드를 문서화해야합니다.


또한, 향후 (및 올바르게 semver'd ) 릴리스 에서 더 이상 사용되지 않는 메소드를 제거하는 것을 잊지 마십시오 . Java 라이브러리와 같은 실수를하지 마십시오.


4
나는 이것이 자바 부분에서 너무 많은 "실수"가 아니라 확실하지 않다. 대부분의 역 호환성 문제 ( stackoverflow.com/questions/314540 참조 ). 맹인은 루비 코드를 고려할 필요가 없다.
VonC

38
코드는 책임입니다. 코드가 적을수록 더 잘 유지해야합니다. 지원 중단은 일시적인 이전 버전과의 호환성에는 좋지만 시간이 지남에 따라 부서지기 쉬워집니다. 사람들이 경우 필요한 은퇴 한 방법을 사용하여, 그들은 대신 라이브러리의 이전 버전을 사용해야합니다.
Ryan McGeary

2
탁월한 반응. 루비 표준 라이브러리에 의존하는 최근에 사용한 접근 방식을 보여주는 응답에 대한 링크를 추가하고 싶습니다. stackoverflow.com/questions/293981/…
Ricardo Valeriano

1
@RicardoValeriano 본인의 답변은 통합 (또는 더 높은 투표 또는 둘 다)되어야한다는 데 동의합니다.
Felix

53

루비 표준 라이브러리는 경고 로직 모듈이 https://ruby-doc.org/stdlib/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.

이 방법을 사용하면 통화 장소에 대한 무료 정보를 얻을 수 있습니다.


니스, 표준 라이브러리에서 이것에 대해 몰랐습니다.
Kris

2
0숫자 리터럴 의 선행 은 8 진이므로 제거해야합니다.
Matt Whipple 2016 년

3
팁 고마워. 나는 전체 수업을 더 이상 사용하지 않고 새로운 수업을 제안했습니다.deprecate :initialize, UseThisClassInstead, 2017, 5
Jon Kern

훌륭한 사용 예, Jon. 정말 좋은 것입니다.
Ricardo Valeriano 님

5
이전 정답은 더 이상 사용되지 않으며 Ricardo Valueriano의 답변을 사용해야합니다.
simon

14

도움이되기를 간절히 원한다면 경고 중에 콜 스택의 첫 번째 줄을 인쇄하여 개발자에게 더 이상 사용되지 않는 호출을 사용하는 위치를 알려줄 수 있습니다.

이것은 성능 저하가 확실 하기 때문에 의미 합니다.

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

올바르게 사용되면 더 이상 사용되지 않는 호출이 사용 된 파일 및 행의 절대 경로가 포함됩니다. Kernel :: caller에 대한 자세한 내용은 여기를 참조하십시오.


5
나는 이것을 의미하지 않습니다. 성능 저하가 적 으면 더 이상 사용되지 않는 호출이 발생한 위치를 쫓아내는 것보다 좋고 메소드가 결국 제거 될 때 깨지는 것보다 훨씬 좋습니다.
Nathan Long

13

ActiveSupport 사용 :

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

프로덕션 환경에서는 기본적으로 경고가 해제되어 있습니다.


12

다음 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)

8

당신은 가지고 있습니다 libdeprecated-ruby(2010-2012, 더 이상 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

링크는 데비안 패키지에 관한 페이지로 연결됩니다. 이것은 비슷해 보이지만 RubyGem입니다 : rubygems.org/gems/deprecated
Benjamin Oakes

3

클래스 매크로 패턴을 사용하여 다음과 같이 작성할 수 있습니다.

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



1

나는 가벼운 방법을 함께 던졌습니다.

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가 필요할 수 있습니다.


0

내부 매크로 메소드를 사용할 수 있습니다. 예:

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) 

지원 중단 : a, : get_a 지원 중단 : b, : get_b 지원 중단 : c, : get_c end

o = Foo.new p oa

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.