কীভাবে আমি কোনও পদ্ধতির উত্স কোডটি গতিশীলভাবে পেতে পারি এবং এই পদ্ধতিতে কোন ফাইলটি চিহ্নিত করা হয়


90

আমি জানতে চাই যে আমি উড়ে যাওয়ার জন্য সোর্স কোডটি একটি পদ্ধতি পেয়েছি এবং এই পদ্ধতিতে কোন ফাইলটি পেতে পারি কিনা তা জানতে চাই।

পছন্দ

A.new.method(:a).SOURCE_CODE
A.new.method(:a).FILE

উত্তর:


117

ব্যবহার source_location:

class A
  def foo
  end
end

file, line = A.instance_method(:foo).source_location
# or
file, line = A.new.method(:foo).source_location
puts "Method foo is defined in #{file}, line #{line}"
# => "Method foo is defined in temp.rb, line 2"

মনে রাখবেন যে বিল্টিন পদ্ধতিগুলির জন্য, source_locationরিটার্ন দেয় nil। যদি সি উত্স কোডটি পরীক্ষা করতে চান (মজা করুন!), আপনাকে সঠিক সি ফাইলটি অনুসন্ধান করতে হবে (তারা শ্রেণি দ্বারা আরও কম সংখ্যক সংগঠিত আছেন) এবং rb_define_methodপদ্ধতিটির জন্য ফাইলটির শেষের দিকে সন্ধান করতে হবে )।

রুবি ১.৮ এ এই পদ্ধতিটি বিদ্যমান নেই তবে আপনি এই রত্নটি ব্যবহার করতে পারেন ।


4
হাই, আমি রুবি ২.6.১ ব্যবহার করে ভবিষ্যত থেকে এসেছি! আমি এর উত্স কোড চাই String#include?। এখনও পর্যন্ত String.instance_method(:include?).source_locationরিটার্ন nil
এস গোস্বামী

39

এখনও পর্যন্ত উত্তরগুলির মধ্যে কোনওটিই দেখায় না যে কীভাবে উড়ে যাওয়ার পদ্ধতিটির উত্স কোডটি প্রদর্শিত হবে ...

এটি আসলে খুব সহজ যদি আপনি জন মায়ার (প্রাই এর নির্মাতা) দ্বারা দুর্দান্ত 'মেথড_সোর্স' রত্ন ব্যবহার করেন: এই পদ্ধতিটি রুবিতে (সি নয়) প্রয়োগ করা যেতে পারে এবং একটি ফাইল থেকে লোড করতে হবে (আইআরবি নয়)।

পদ্ধতি_সোর্স সহ রেল কনসোলে পদ্ধতি উত্স কোড প্রদর্শন করার জন্য এখানে একটি উদাহরণ রয়েছে:

  $ rails console
  > require 'method_source'
  > I18n::Backend::Simple.instance_method(:lookup).source.display
    def lookup(locale, key, scope = [], options = {})
      init_translations unless initialized?
      keys = I18n.normalize_keys(locale, key, scope, options[:separator])

      keys.inject(translations) do |result, _key|
        _key = _key.to_sym
        return nil unless result.is_a?(Hash) && result.has_key?(_key)
        result = result[_key]
        result = resolve(locale, _key, result, options.merge(:scope => nil)) if result.is_a?(Symbol)
        result
      end
    end
    => nil 

আরো দেখুন:


4
আমি রুবিতে সবসময় এই বৈশিষ্ট্যটি মিস করেছি। লিস্প এটি করতে পারে :)
টিলো

ক্লোজারের থেকে আসছে source। এটি প্রত্যাশার মতো কাজ করে।
সেবাস্তিয়ান পালমা

আমি এই ত্রুটিটি পেয়েছি: [1] pry(main)> RSpec.method(:class_exec).source MethodSource::SourceNotFoundError: Could not locate source for class_exec! from /home/vagrant/.bundle/foo/ruby/2.5.0/gems/method_source-0.9.2/lib/method_source.rb:24:in `source_helper'
আব্রাম

RSpec.method(:to_json).source_locationযদিও ভাল কাজ করে
আব্রাম

17

রুবি থেকে উত্স কোডটি কীভাবে প্রিন্ট করা যায় তা এখানে:

puts File.read(OBJECT_TO_GET.method(:METHOD_FROM).source_location[0])

10

নির্ভরতা ছাড়াই

method = SomeConstant.method(:some_method_name)
file_path, line = method.source_location
# puts 10 lines start from the method define 
IO.readlines(file_path)[line-1, 10]

আপনি যদি আরও সুবিধে করে এটি ব্যবহার করতে চান তবে আপনি Methodক্লাসটি খুলতে পারেন :

# ~/.irbrc
class Method
  def source(limit=10)
    file, line = source_location
    if file && line
      IO.readlines(file)[line-1,limit]
    else
      nil
    end
  end
end

এবং তারপর শুধু কল method.source

প্রাইয়ের সাহায্যে আপনি show-methodকোনও পদ্ধতির উত্স দেখতে ব্যবহার করতে পারেন , এবং আপনি কোডে-ব্রাউজিংয়ে পিএসpry-doc এর ডক অনুযায়ী ইনস্টলড সহ কিছু রুবি সি সোর্স কোড দেখতে পারেন

নোট করুন যে আমরা পি-ডক প্লাগইন ব্যবহার করে সি পদ্ধতিগুলি (রুবি কোর থেকে )ও দেখতে পারি; আমরা শো-পদ্ধতির জন্য বিকল্প সিনট্যাক্সটিও প্রদর্শন করি:

pry(main)> show-method Array#select

From: array.c in Ruby Core (C Method):
Number of lines: 15

static VALUE
rb_ary_select(VALUE ary)
{
    VALUE result;
    long i;

    RETURN_ENUMERATOR(ary, 0, 0);
    result = rb_ary_new2(RARRAY_LEN(ary));
    for (i = 0; i < RARRAY_LEN(ary); i++) {
        if (RTEST(rb_yield(RARRAY_PTR(ary)[i]))) {
            rb_ary_push(result, rb_ary_elt(ary, i));
        }
    }
    return result;
}

sourceএটি Methodক্লাসের ভিতরে একটি পদ্ধতির জন্য দুর্দান্ত ধারণা । এটি আরও ভাল হবে যদি এটি পাঠ্যটি প্রক্রিয়াকরণ করে এবং মুদ্রণ বন্ধ করতে কখন নতুন হয় কারণ এটি পদ্ধতির শেষে পৌঁছেছে।
টবি 1 কেনোবি

4

আমি এই উদ্দেশ্যে "ri_for" রত্ন তৈরি করেছি

 >> require 'ri_for'
 >> A.ri_for :foo

... উত্সটি আউটপুট করে (এবং আপনি যদি 1.9 তে অবস্থান করেন)।

জিএল। -আর


এই সব আমার জন্য একটি বিভাজন ত্রুটি উত্পাদন করছে। :(
পানিজি

সেগ দোষ পুনরুত্পাদন কিভাবে? কোন পদ্ধতি / শ্রেণি?
রজারডপ্যাক

1

রং এর অংশ হিসাবে আমাকে অনুরূপ বৈশিষ্ট্যটি (একটি ব্লকের উত্সটি ধরতে হবে) বাস্তবায়ন করতে হয়েছিল এবং আপনি দেখতে পাচ্ছেন কীভাবে (এবং সম্ভবত কোডটি পুনরায় ব্যবহারও করতে হবে ) chunk.rb (যা রায়ান ডেভিসের রুবিপার্সারের উপর নির্ভর করে পাশাপাশি কিছু মজার মজার) উত্স ফাইল গ্লোমিং কোড )। আপনাকে এটি ব্যবহারের জন্য পরিবর্তন করতে হবে Method#source_locationএবং সম্ভবত কিছু অন্যান্য জিনিস টুইট করতে হবে যাতে এটি অন্তর্ভুক্ত করে না বা অন্তর্ভুক্ত করে না def

বিটিডাব্লু আমি মনে করি রুবিনিয়াসের এই বৈশিষ্ট্যটি অন্তর্নির্মিত রয়েছে some কিছু কারণে এটি এমআরআই (মানক রুবি বাস্তবায়ন) থেকে বাদ পড়েছে, তাই এই হ্যাক।

ওহ, আমি পদ্ধতি_সূত্রের কিছু স্টাফ পছন্দ করি ! যেমন কোনও অভিব্যক্তিটি বৈধ কিনা তা জানাতে ইওল ব্যবহার করা (এবং চঙ্কের মতো পার্স ত্রুটিগুলি থামানো অবধি গ্লোমিং সোর্স লাইনগুলি রাখুন) ...


1

অভ্যন্তরীণ পদ্ধতিতে উত্স বা উত্সের অবস্থান নেই (যেমন Integer#to_s)

require 'method_source'
User.method(:last).source
User.method(:last).source_location
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.