রুবিতে অবচয় কোড চিহ্নিত করার সেরা অনুশীলন?


127

আমি কোনও পদ্ধতিটিকে অবহেলিত হিসাবে চিহ্নিত করতে চাই, তাই এটির লোকেরা সহজেই তাদের কোডটি চেক করতে এবং ধরতে পারে। জাভাতে আপনি @ বিশিষ্ট সেট করেছেন এবং সকলেই জানেন যে এর অর্থ কী।

তাহলে কি রুবিতে অবচয় চিহ্নিত করার জন্য চিহ্নিত করার জন্য কোনও পছন্দসই উপায় (বা এমনকি সরঞ্জাম) রয়েছে?


ন্যায়সঙ্গত হওয়ার জন্য, জাভার টীকাগুলি সফল হয়, কারণ এটির কোনও সম্ভাব্য প্রতিস্থাপনের দিকে নির্দেশ করার কোনও মূল্য নেই
হাইকো রুপ

উত্তর:


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

অবচিত: ইঙ্গিত করে যে পদ্ধতিটি হ্রাস পেয়েছে এবং ভবিষ্যতের সংস্করণে সরানো হবে। আপনি পাবলিক ছিল এমন ডকুমেন্ট পদ্ধতিতে এটি ব্যবহার করা উচিত তবে পরবর্তী বড় সংস্করণে এটি সরানো হবে।


এছাড়াও, কিছু ভবিষ্যতে (এবং সঠিকভাবে semver 'd) রিলিজে অবচিত পদ্ধতি মুছে ফেলতে ভুলবেন না । জাভা লাইব্রেরিগুলির মতো একই ভুল করবেন না।


4
আমি নিশ্চিত এটা এত একটি জাভা অংশ থেকে "ভুল", বরং বিপুল অনুন্নত সহাবস্থানযোগ্যতা ইস্যু (দেখুন নই stackoverflow.com/questions/314540 ), যে blindgaenger তার রুবি কোড বিবেচনা করতে হবে না।
ভোনসি

38
কোড একটি দায়বদ্ধতা। আপনার কম কোডটি আরও ভাল বজায় রাখতে হবে। অস্থায়ী পিছনের সামঞ্জস্যের জন্য অবচয়গুলি ভাল, তবে সময়ের সাথে সাথে এটি ক্রাফ্ট হয়ে যায়। লোকদের যদি অবসরপ্রাপ্ত পদ্ধতিগুলি ব্যবহার করার প্রয়োজন হয় তবে তাদের পরিবর্তে আপনার লাইব্রেরির পুরানো সংস্করণগুলি ব্যবহার করা উচিত।
রায়ান ম্যাকগেরি 21

2
অসাধারণ সাড়া। আমি কেবলমাত্র প্রতিক্রিয়াটির একটি লিঙ্ক যুক্ত করতে চাই যেখানে আমি যে পদ্ধতিটি ব্যবহার করেছি যা আমি ইদানীং ব্যবহার করেছি, যা রুবি স্টাড লিবের উপর নির্ভর করে: স্ট্যাকওভারফ্লো
রিকার্ডো ভ্যালারিওনো

1
@ রিকার্ডোভ্যালারিও আমি সম্মত, আপনার প্রতিক্রিয়াটি সংহত করা উচিত (বা উচ্চতর ভোট দেওয়া, বা উভয় :))।
ফেলিক্স

53

রুবি স্ট্যান্ডার্ড লাইব্রেরিতে সতর্কতা যুক্তি সহ একটি মডিউল রয়েছে: https://ruby-doc.org/stdlib/libdoc/rubygems/rdoc/Gem/Drerecate.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

অ্যাক্টিভসপোর্ট:

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(২০১০-২০১২, 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

লিঙ্কটি আমাকে একটি ডেবিয়ান প্যাকেজ সম্পর্কিত পৃষ্ঠায় নিয়ে যায়। এটি একইরকম মনে হয় (একইরকম না হলে) এবং এটি একটি রুবিগেম: রুবিজেমস.অর্গ
বেনিয়ামিন ওকে

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 অবচয়: বি,: get_b অবচয়: সি,: get_c সমাপ্তি

o = Foo.new p oa

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.