2008-11-16 20 views
111

Tôi muốn đánh dấu một phương pháp là không được chấp nhận, vì vậy những người sử dụng nó có thể dễ dàng kiểm tra mã của họ và bắt kịp. Trong Java, bạn thiết lập @Deprecated và mọi người đều biết điều này có nghĩa là gì.Phương pháp hay nhất để đánh dấu mã không dùng nữa trong Ruby?

Vì vậy, có cách nào ưa thích (hoặc thậm chí là công cụ) để đánh dấu và kiểm tra việc ngừng sử dụng trong Ruby?

+0

Để công bằng, chú thích Java sucks, vì nó không có giá trị để trỏ đến một sự thay thế tiềm năng –

Trả lời

144

Đối với hầu như tất cả các trường hợp, tùy thuộc vào thư viện hoặc lập trình meta cho việc không dùng nữa là quá mức cần thiết. Chỉ cần thêm một bình luận vào rdoc và gọi phương thức Kernel#warn. Ví dụ:

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 

Nếu bạn đang sử dụng Yard thay vì rdoc, bình luận doc của bạn sẽ giống như thế này:

# @deprecated Please use {#useful} instead 

Cuối cùng, nếu bạn tuân thủ tomdoc, hãy nhìn nhận xét của bạn như thế này:

# Deprecated: Please use `useful` instead 

Không được chấp nhận: Cho biết rằng phương pháp không được chấp nhận và sẽ bị xóa trong phiên bản sau. Bạn NÊN sử dụng phương thức này để tài liệu là Public nhưng sẽ bị xóa ở phiên bản chính tiếp theo.


Ngoài ra, đừng quên để loại bỏ các phương pháp phản đối trong một số trong tương lai (và đúng semver 'd) phát hành. Đừng làm những sai lầm tương tự như các thư viện Java đã làm.

+3

Tôi không chắc nó là một "sai lầm" nhiều từ phần Java, chứ không phải là một vấn đề tương thích ngược rất lớn (xem http://stackoverflow.com/questions/314540), người mù đó có thể không cần xem xét mã Ruby của anh ta. – VonC

+33

Mã là trách nhiệm pháp lý. Ít mã bạn phải duy trì tốt hơn. Khấu hao là tốt cho khả năng tương thích ngược, nhưng theo thời gian nó trở thành cruft. Nếu mọi người * cần * để sử dụng các phương thức đã nghỉ hưu, họ nên sử dụng các phiên bản cũ hơn của thư viện của bạn. –

+2

Phản hồi Excel. Tôi chỉ muốn thêm một liên kết đến phản hồi nơi tôi hiển thị cách tiếp cận mà tôi đã sử dụng gần đây, dựa trên Ruby Std Lib: http://stackoverflow.com/questions/293981/best-practice-to-mark-deprecated -code-in-ruby/23554720 # 23554720 –

7

Bạn có libdeprecated-ruby (2010-2012, không có sẵn nữa trên rubygem trong 2015)

Một thư viện nhỏ nhằm hỗ trợ các nhà phát triển làm việc với mã không dùng nữa.
Ý tưởng xuất phát từ ngôn ngữ lập trình 'D', nơi nhà phát triển có thể đánh dấu một số mã nhất định như không được chấp nhận và sau đó cho phép/không cho phép khả năng thực thi mã không dùng nữa.

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 
+0

Liên kết đưa tôi đến một trang về gói Debian. Điều này có vẻ tương tự (nếu không giống nhau) và là một RubyGem: https://rubygems.org/gems/deprecated –

12

Nếu bạn muốn trở thành trung bình (dưới hình thức hữu ích), bạn có thể in ra dòng đầu tiên của callstack trong một cảnh báo để cho dev biết nơi họ đang sử dụng một cuộc gọi không được chấp nhận.

Điều này có nghĩa là vì Tôi chắc chắn đó là hiệu suất đạt được.

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

Khi được sử dụng chính xác, điều này sẽ bao gồm đường dẫn tuyệt đối vào tệp và đường mà cuộc gọi không được dùng đã được sử dụng. Thông tin thêm về Kernel :: người gọi có sẵn here

+3

Tôi không xem xét điều này có nghĩa là. Một hit hiệu suất nhỏ là đẹp hơn phải đuổi theo nơi mà các cuộc gọi không được chấp nhận là, và đẹp hơn nhiều so với một cái gì đó phá vỡ khi phương pháp này cuối cùng đã được gỡ bỏ. –

1

Canivete là một loại đá quý cho phép bạn ngừng sử dụng các phương pháp một cách đơn giản và thanh lịch. Thêm một chút về nó here.

3

Bạn có thể sử dụng Class Macros mẫu và viết một cái gì đó như thế này:

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 
3

Khi sử dụng đường ray, bạn có Module phương pháp # Không dùng nữa.

6

Bạn cũng có thể sử dụng ActiveSupport::Deprecation (có sẵn trong phiên bản 4.0 +), như vậy:

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) 
36

của Ruby thư viện chuẩn có một mô-đun với logic cảnh báo: http://ruby-doc.org/stdlib-1.9.3/libdoc/rubygems/rdoc/Gem/Deprecate.html. Tôi có xu hướng thích nó để duy trì thông điệp deprecation của tôi trong một cách "chuẩn":

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

Lưu ý rằng với cách tiếp cận này, bạn sẽ đạt được cung cấp thông tin miễn phí về nơi cuộc gọi diễn ra.

+0

Tốt, không biết về điều này trong lib chuẩn. – Kris

+0

Rất vui được giúp đỡ, Kris! –

+2

hàng đầu '0' cho một chữ số làm cho nó bát phân và do đó có thể sẽ bị xóa. –

1

tôi đã kết thúc ném cùng một phương pháp nhẹ:

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

Sau đó không chấp một phương pháp chèn một cuộc gọi trong cơ thể phương pháp (hoặc một constructor cho một lớp)

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

Đó là khá declarative và cung cấp thông tin đăng nhập có liên quan. Tôi không phải là một Rubyist vì vậy nó có thể cần một số tinh chỉnh/YMMV.

6

Sử dụng ActiveSupport:

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

Cảnh báo được tắt trong môi trường sản xuất theo mặc định

Các vấn đề liên quan