Antworten:
Verwendung 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"
Beachten Sie, dass für builtin Methoden, source_location
kehrt nil
. Wenn Sie den C-Quellcode überprüfen möchten (viel Spaß!), Müssen Sie nach der richtigen C-Datei suchen (sie sind mehr oder weniger nach Klassen organisiert) und die rb_define_method
für die Methode finden (gegen Ende der Datei) ).
In Ruby 1.8 existiert diese Methode nicht, aber Sie können dieses Juwel verwenden .
Keine der bisherigen Antworten zeigt, wie der Quellcode einer Methode im laufenden Betrieb angezeigt wird ...
Es ist eigentlich sehr einfach, wenn Sie das großartige Juwel 'method_source' von John Mair (dem Hersteller von Pry) verwenden: Die Methode muss in Ruby (nicht C) implementiert und aus einer Datei (nicht irb) geladen werden.
Hier ist ein Beispiel für die Anzeige des Methodenquellcodes in der Rails-Konsole mit 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
Siehe auch:
source
. Dies funktioniert wie erwartet.
[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
funktioniert aber gut
So drucken Sie den Quellcode von Ruby aus:
puts File.read(OBJECT_TO_GET.method(:METHOD_FROM).source_location[0])
Ohne Abhängigkeiten
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]
Wenn Sie dies bequemer verwenden möchten, können Sie die Method
Klasse öffnen :
# ~/.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
Und dann einfach anrufen method.source
Mit Pry können Sie die verwenden show-method
, um eine Methodenquelle anzuzeigen, und Sie können sogar Ruby C-Quellcode mit pry-doc
installiertem Code anzeigen, wie in Prys Dokument in Codde-Browing angegeben
Beachten Sie, dass wir C-Methoden (aus Ruby Core) auch mit dem pry-doc-Plugin anzeigen können. Wir zeigen auch die alternative Syntax für die Show-Methode:
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
Methode innerhalb der Method
Klasse. Es wäre sogar noch besser, wenn der Text verarbeitet würde und neu, wann der Druckvorgang beendet werden soll, da das Ende der Methode erreicht ist.
Zu diesem Zweck habe ich das Juwel "ri_for" erstellt
>> require 'ri_for'
>> A.ri_for :foo
... gibt die Quelle aus (und den Ort, wenn Sie auf 1.9 sind).
GL. -r
Ich musste eine ähnliche Funktion (greifen Sie nach der Quelle eines Blocks) als Teil von Wrong implementieren, und Sie können sehen, wie (und vielleicht sogar den Code wiederverwenden) in chunk.rb (das sich auf Ryan Davis 'RubyParser stützt, sowie einige ziemlich lustige Quelldatei glomming Code ). Sie müssten es ändern, um es zu verwenden, Method#source_location
und vielleicht einige andere Dinge optimieren, damit es das enthält oder nicht def
.
Übrigens, ich denke, Rubinius hat diese Funktion eingebaut. Aus irgendeinem Grund wurde sie aus der MRT (der Standard-Ruby-Implementierung) herausgelassen, daher dieser Hack.
Oooh, ich mag einige Sachen in method_source ! Wie mit eval zu sagen , ob ein Ausdruck gültig ist (und halten glomming Source - Leitungen , bis Sie aufhören immer Parse - Fehler, wie Chunk der Fall ist) ...
String#include?
. SoweitString.instance_method(:include?).source_location
kehrt zurücknil
.