ruby on rails - কিভাবে একটি পদ্ধতি রানটাইম এ সংজ্ঞায়িত করা হয়?




ruby-on-rails runtime (7)

আমরা সম্প্রতি একটি সমস্যা ছিল, যেখানে একটি সিরিজ ঘটেছে, একটি ব্যাকঅ্যান্ড প্রক্রিয়া চালানো ব্যর্থ হয়েছে। এখন, আমরা ছোট ছোট ছেলেমেয়েরা ছিলাম এবং প্রতি চেক- rake test পরে rake test চালাচ্ছিলাম, কিন্তু রেলস লাইব্রেরির লোডিংয়ের কিছু অদ্ভুততার কারণে, এটি তখনই ঘটেছিল যখন আমরা সরাসরি উৎপাদন মঞ্চে মংগল থেকে এটি দৌড়েছিলাম।

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

যাইহোক, দীর্ঘ গল্প সংক্ষিপ্ত, রানটাইম এ কোন উপায় আছে, রুবি জিজ্ঞাসা করার পদ্ধতি যেখানে একটি পদ্ধতি সংজ্ঞায়িত করা হয়েছে? whereami( :foo ) মত কিছু whereami( :foo ) যে /path/to/some/file.rb line #45 ? এই ক্ষেত্রে, আমাকে বলা হয়েছে যে এটি শ্রেণির স্ট্রিংয়ের মধ্যে সংজ্ঞায়িত করা অসম্ভব, কারণ এটি কিছু লাইব্রেরি দ্বারা ওভারলোড করা হয়েছিল।

আমি আমার প্রোজেক্টের উৎসের গ্যারান্টিকে গ্যারান্টী দিতে পারছি না, তাই 'def foo' জন্য grepping অগত্যা আমাকে যা প্রয়োজন তা দিতে হবে না, আমার অনেক def foo আছে উল্লেখ না করে, কখনও কখনও আমি রানটাইম পর্যন্ত জানি না কোনটি। ব্যবহার করা হতে পারে।


আপনি আসলে উপরে সমাধান চেয়ে একটু বেশি যেতে পারেন। রুবি 1.8 এন্টারপ্রাইজ সংস্করণের জন্য, পদ্ধতির __line__ __file__ এবং __line__ পদ্ধতি রয়েছে:

require 'rubygems'
require 'activesupport'

m = 2.days.method(:ago)
# => #<Method: Fixnum(ActiveSupport::CoreExtensions::Numeric::Time)#ago>

m.__file__
# => "/Users/james/.rvm/gems/ree-1.8.7-2010.01/gems/activesupport-2.3.8/lib/active_support/core_ext/numeric/time.rb"
m.__line__
# => 64

রুবি 1.9 এবং এর বাইরে, source_location (ধন্যবাদ জনাথন!):

require 'active_support/all'
m = 2.days.method(:ago)
# => #<Method: Fixnum(Numeric)#ago>    # comes from the Numeric module

m.source_location   # show file and line
# => ["/var/lib/gems/1.9.1/gems/activesupport-3.0.6/.../numeric/time.rb", 63]

আপনি এই মত কিছু করতে সক্ষম হতে পারে:

foo_finder.rb:

 class String
   def String.method_added(name)
     if (name==:foo)
        puts "defining #{name} in:\n\t"
        puts caller.join("\n\t")
     end
   end
 end

তারপর foo_finder ভালো কিছু সঙ্গে লোড করা হয় তা নিশ্চিত করুন

ruby -r foo_finder.rb railsapp

(আমি কেবল রেলের সাথে জড়িয়ে পড়েছি, তাই আমি ঠিক জানি না, কিন্তু আমি মনে করি এটির মতো এটি শুরু করার উপায় রয়েছে।)

এটি আপনাকে স্ট্রিং # foo এর সমস্ত পুনরায় সংজ্ঞাগুলি দেখাবে। সামান্য মেটা প্রোগ্রামিং সঙ্গে, আপনি চান যাই হোক না কেন ফাংশন জন্য এটি সাধারণকরণ করতে পারে। কিন্তু এটি ফাইলটির আগে লোড করা দরকার যা প্রকৃতপক্ষে পুনরায় সংজ্ঞা দেয়।


আমি এই থ্রেডে দেরিতে আসছি, এবং কেউ অবাক হচ্ছেন যে Method#owner উল্লেখ নেই।

class A; def hello; puts "hello"; end end
class B < A; end
b = B.new
b.method(:hello).owner
=> A

একটি নতুন অনুরূপ প্রশ্ন থেকে আমার উত্তর অনুলিপি করা যা এই সমস্যার নতুন তথ্য যোগ করে।

Ruby 1.9 source_location নামক পদ্ধতি আছে:

এই পদ্ধতিটি Ruby উৎস ফাইলনাম এবং লাইন নম্বরটি এই পদ্ধতি ধারণ করে না অথবা যদি এই পদ্ধতিটি রুবি (অর্থাৎ নেটিভ)

এই মণির দ্বারা 1.8.7 ব্যাকপোর্ট করা হয়েছে:

সুতরাং আপনি পদ্ধতির জন্য অনুরোধ করতে পারেন:

m = Foo::Bar.method(:create)

এবং তারপর সেই পদ্ধতির source_location জন্য জিজ্ঞাসা করুন:

m.source_location

এটি ফাইলের নাম এবং লাইন নম্বর সহ একটি অ্যারে ফেরত দেবে। যেমন ActiveRecord::Base#validates এই আয়গুলি ActiveRecord::Base#validates :

ActiveRecord::Base.method(:validates).source_location
# => ["/Users/laas/.rvm/gems/[email protected]/gems/activemodel-3.2.2/lib/active_model/validations/validates.rb", 81]

ক্লাস এবং মডিউলগুলির জন্য, রুবি সমর্থনে নির্মিত অফার দেয় না, তবে সেখানে একটি চমৎকার পদ্ধতি রয়েছে যা প্রদত্ত পদ্ধতির জন্য ফাইলটি ফেরত দিতে source_location এবং কোনো পদ্ধতি নির্দিষ্ট না হলে ক্লাসের জন্য প্রথম ফাইলটি তৈরি করে:

কর্মে:

where_is(ActiveRecord::Base, :validates)

# => ["/Users/laas/.rvm/gems/[email protected]/gems/activemodel-3.2.2/lib/active_model/validations/validates.rb", 81]

টেক্সটমেট ইনস্টল করা ম্যাকগুলিতে, এটি নির্দিষ্ট অবস্থানে সম্পাদককেও পপ আপ করে।


এটি সাহায্য করতে পারে তবে আপনাকে এটি নিজের কোড করতে হবে। ব্লগ থেকে পেস্ট করা হয়েছে:

রুবি একটি method_added () কলব্যাক সরবরাহ করে যা প্রতিবার একটি পদ্ধতি যোগ করা হয় বা একটি শ্রেণির মধ্যে পুনরায় সংজ্ঞায়িত করা হয়। এটি মডিউল ক্লাসের অংশ এবং প্রতিটি ক্লাস একটি মডিউল। Method_removed () এবং method_undefined () নামে দুটি সম্পর্কিত কলব্যাক রয়েছে।

http://scie.nti.st/2008/9/17/making-methods-immutable-in-ruby


খুব দেরী উত্তর :) কিন্তু আগে উত্তর আমাকে সাহায্য করেনি

set_trace_func proc{ |event, file, line, id, binding, classname|
  printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
}
# call your method
set_trace_func nil

সম্ভবত #source_location এখান থেকে পদ্ধতিটি কোথায় খুঁজে পেতে সাহায্য করতে পারে।

উদা:

ModelName.method(:has_one).source_location

প্রত্যাবর্তন

[project_path/vendor/ruby/version_number/gems/activerecord-number/lib/active_record/associations.rb", line_number_of_where_method_is]

অথবা

ModelName.new.method(:valid?).source_location

প্রত্যাবর্তন

[project_path/vendor/ruby/version_number/gems/activerecord-number/lib/active_record/validations.rb", line_number_of_where_method_is]




definition