Saya ingin tahu apakah saya bisa mendapatkan kode sumber suatu metode dengan cepat, dan apakah saya bisa mendapatkan file mana dengan metode ini.
Suka
A.new.method(:a).SOURCE_CODE
A.new.method(:a).FILE
Penggunaan 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"
Perhatikan bahwa untuk metode bawaan, source_location
mengembalikan nil
. Jika ingin memeriksa kode sumber C (selamat bersenang-senang!), Anda harus mencari file C yang tepat (mereka kurang lebih diatur berdasarkan kelas) dan menemukan rb_define_method
metode untuk (menjelang akhir file ).
Di Ruby 1.8 metode ini tidak ada, tetapi Anda dapat menggunakan permata ini .
String#include?
. Sejauh iniString.instance_method(:include?).source_location
kembalinil
.Sejauh ini tidak ada jawaban yang menunjukkan cara menampilkan kode sumber dari suatu metode dengan cepat ...
Sebenarnya sangat mudah jika Anda menggunakan permata 'method_source' yang mengagumkan dari John Mair (pembuat Pry): Metode ini harus diimplementasikan di Ruby (bukan C), dan harus dimuat dari file (bukan irb).
Berikut adalah contoh yang menampilkan kode sumber metode di konsol Rails dengan method_source:
$ 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
Lihat juga:
sumber
source
. Ini bekerja seperti yang diharapkan.[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
bekerja dengan baik meskipunBerikut adalah cara mencetak kode sumber dari ruby:
puts File.read(OBJECT_TO_GET.method(:METHOD_FROM).source_location[0])
sumber
Tanpa ketergantungan
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]
Jika Anda ingin menggunakan ini lebih nyaman, Anda dapat membuka
Method
kelas:# ~/.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
Dan kemudian panggil saja
method.source
Dengan Pry Anda dapat menggunakan
show-method
untuk melihat sumber metode, dan Anda bahkan dapat melihat beberapa kode sumber ruby c denganpry-doc
diinstal, menurut dokumen pry di codde-browingsumber
source
metode di dalamMethod
kelas. Akan lebih baik lagi jika teks itu diproses dan baru kapan harus berhenti mencetak karena sudah mencapai akhir metode.Saya membuat permata "ri_for" untuk tujuan ini
>> require 'ri_for' >> A.ri_for :foo
... mengeluarkan sumber (dan lokasi, jika Anda menggunakan 1.9).
GL. -r
sumber
Saya harus menerapkan fitur serupa (ambil sumber blok) sebagai bagian dari Salah dan Anda dapat melihat bagaimana (dan bahkan mungkin menggunakan kembali kode) di chunk.rb (yang bergantung pada RubyParser Ryan Davis dan juga beberapa yang cukup lucu kode sumber file glomming ). Anda harus memodifikasinya untuk digunakan
Method#source_location
dan mungkin mengubah beberapa hal lain sehingga ada atau tidak termasuk filedef
.BTW Saya pikir Rubinius memiliki fitur bawaan ini. Untuk beberapa alasan fitur ini telah ditinggalkan dari MRI (implementasi Ruby standar), karenanya hack ini.
Oooh, saya suka beberapa item di method_source ! Seperti menggunakan eval untuk mengetahui apakah ekspresi itu valid (dan terus glomming baris sumber sampai Anda berhenti mendapatkan kesalahan parse, seperti Chunk) ...
sumber
Metode internal tidak memiliki sumber atau lokasi sumber (misalnya
Integer#to_s
)require 'method_source' User.method(:last).source User.method(:last).source_location
sumber