रूबी में पदावनत कोड को चिह्नित करने के लिए सबसे अच्छा अभ्यास?


127

मैं पदावनत विधि को चिह्नित करना चाहता हूं, इसलिए इसका उपयोग करने वाले लोग आसानी से अपने कोड की जांच कर सकते हैं और पकड़ सकते हैं। जावा में आपने @Deprecated सेट किया है और हर कोई जानता है कि इसका क्या मतलब है।

तो क्या रूबी में पदावनतियों को चिह्नित करने और जांचने के लिए एक पसंदीदा तरीका (या यहां तक ​​कि उपकरण) है?


निष्पक्ष होने के लिए, जावा का एनोटेशन बेकार है, क्योंकि संभावित प्रतिस्थापन को इंगित करने के लिए इसका कोई मूल्य नहीं है
हेइको रूप्प

जवाबों:


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 के बजाय यार्ड का उपयोग कर रहे हैं , तो आपकी दस्तावेज़ टिप्पणी इस तरह दिखनी चाहिए:

# @deprecated Please use {#useful} instead

अंत में, यदि आप टोमडॉक का पालन करते हैं , तो अपनी टिप्पणी इस तरह करें:

# Deprecated: Please use `useful` instead

पदावनत: इंगित करता है कि विधि पदावनत है और भविष्य के संस्करण में हटा दी जाएगी। आप इसे दस्तावेज़ विधियों के लिए उपयोग कर सकते हैं जो सार्वजनिक थे लेकिन अगले प्रमुख संस्करण में हटा दिए जाएंगे।


इसके अलावा, कुछ भविष्य में (और ठीक से सेवर 'डी) जारी किए गए पदावनत विधि को हटाना न भूलें । जावा पुस्तकालयों ने वही गलतियाँ नहीं कीं।


4
मुझे यकीन नहीं है कि यह जावा भाग से बहुत अधिक "गलती" है, बल्कि एक बड़ी पिछड़ी संगतता समस्या है (देखें stackoverflow.com/questions/314540 ), कि ब्लागेंगर को अपने रूबी कोड के लिए विचार करने की आवश्यकता नहीं हो सकती है।
VONC

38
कोड एक दायित्व है। कम कोड आपको बेहतर बनाए रखना होगा। डिप्रेशन अस्थायी पश्चगामी संगतता के लिए अच्छा है, लेकिन समय के साथ यह कम हो जाता है। यदि लोगों को सेवानिवृत्त तरीकों का उपयोग करने की आवश्यकता है, तो उन्हें आपके पुस्तकालयों के पुराने संस्करणों का उपयोग करना चाहिए।
रयान मैक्ग्रे

2
एक्सेलेंट प्रतिक्रिया। मैं सिर्फ प्रतिक्रिया के लिए एक लिंक जोड़ना चाहता हूं, जहां मैं उस दृष्टिकोण को दिखाता हूं, जिसका मैंने हाल ही में उपयोग किया है, जो रूबी Std Lib पर निर्भर करता है: stackoverflow.com/questions/293981/…
Ricardo Valeriano

1
@RicardoValeriano मैं सहमत हूं, आपकी प्रतिक्रिया एकीकृत होनी चाहिए (या उच्चतर मतदान, या दोनों :))।
फेलिक्स

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.

ध्यान दें कि इस दृष्टिकोण के साथ आप मुफ्त जानकारी प्राप्त करेंगे कि कॉल कहां हुआ था।


अच्छा है, मानक परिवाद में इस बारे में पता नहीं था।
क्रिश

2
0एक संख्यात्मक शाब्दिक के लिए अग्रणी इसे अष्टाधारी बनाता है और इसलिए इसे हटा दिया जाना चाहिए।
मैट व्हिपल

3
पारितोषिक के लिए धन्यवाद। मैंने एक पूरी कक्षा को हटा दिया, और नए वर्ग का उपयोग करने का सुझाव दिया:deprecate :initialize, UseThisClassInstead, 2017, 5
जॉन केर्न

महान उपयोग उदाहरण, जॉन। वास्तव में अच्छा है।
रिकार्डो वेलेरियानो

5
पिछले सही उत्तर को हटा दिया गया है और रिकार्डो वेलूरियानो द्वारा उपयोग किए जाने वाले उत्तर का अब उपयोग किया जाना चाहिए
सिमोन

14

यदि आप मतलब चाहते हैं (सहायक होने की आड़ में) तो आप चेतावनी के दौरान कॉलस्टैक की पहली पंक्ति को प्रिंट कर सकते हैं ताकि देवों को पता चल सके कि वे एक पदावनत कॉल का उपयोग कर रहे हैं।

इसका मतलब यह है क्योंकि मुझे पूरा यकीन है कि यह एक प्रदर्शन-हिट है।

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

जब सही तरीके से उपयोग किया जाता है, तो यह फ़ाइल और लाइन के पूर्ण पथ को शामिल करेगा जहां पदावनत कॉल का उपयोग किया गया था। कर्नेल :: कॉलर के बारे में अधिक जानकारी यहाँ उपलब्ध है


5
मैं इसका मतलब नहीं समझता। एक छोटा सा प्रदर्शन हिट नीच का पीछा करने की तुलना में अच्छा है जहां पदावनत कॉल था, और विधि के अंत में हटाए जाने पर कुछ टूटने की तुलना में बहुत अच्छे।
नाथन लोंग

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(२०१०-२०१२, २०१५ में माणिक्य पर उपलब्ध नहीं है)

एक छोटा सा पुस्तकालय जिसका उद्देश्य अपवित्र कोड के साथ काम करने वाले डेवलपर्स की सहायता करना है।
यह विचार ' 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

लिंक मुझे एक डेबियन पैकेज के बारे में एक पृष्ठ पर ले जाता है। यह समान लगता है (यदि समान नहीं है) और रूबीगैम है: rubygems.org/gems/deprecated
बेंजामिन ने

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

यह काफी घोषणात्मक है और प्रासंगिक जानकारी के साथ लॉगिंग प्रदान करता है। मैं ज्यादा रूबीवादी नहीं हूं, इसलिए इसे कुछ ट्वीकिंग / वाईएमएमवी की जरूरत पड़ सकती है।


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, :__c अंत

o = Foo.new p oa

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.