Mam to pytanie od this discussion. Wywołanie metody, takie jak object.m
, nie zawsze oznacza, że klasa "obiektu" ma metodę "m", tak jak metoda wyszukiwania obiektu Array nie pochodzi bezpośrednio z obiektu Array, lecz z mieszanego modułu Enumerable. Moje pytanie brzmi: w jaki sposób możemy ustalić klasę, z której wywodzi się ta metoda?Jak określić klasę, z której pochodzi określona metoda?
Odpowiedz
Każda metoda klasy/obiektu jest obiektem w języku Ruby i ma kilka własnych metod.
Więc można to zrobić:
[].method(:count).inspect
=> "#<Method: Array#count>"
[].method(:detect).inspect
=> "#<Method: Array(Enumerable)#detect>"
Krótki kawałek RegEx i gotowe.
może użyć dzwoniącego(), aby dać Ci Stolicę backtrace:
myślę coś takiego może pracować
def print_ancestor_definitions(cl,method)
ancestors = cl.ancestors
p ancestors.join(' < ') #Print heirarchy
p "Searching..."
ancestors.each do |c|
if c.instance_methods.include? method
p "#{c} defines #{method} as an instance method!"
elsif c.singleton_methods.include? method
p "#{c} defines #{method} as a singleton method"
else
p "#{c} doesn't define #{method}"
end
end
end
print_ancestor_definitions(Array,'find')
# >> "Array < Enumerable < Object < Kernel"
# >> "Searching..."
# >> "Array defines find as an instance method!"
# >> "Enumerable defines find as an instance method!"
# >> "Object doesn't define find"
# >> "Kernel doesn't define find"
Przypuszczam ostatnia mieć metoda jest tą, która ją definiuje?
Nie jestem pewien, czy możemy dokładnie określić, skąd bierze się metoda, kiedy dodajesz mixin, wszystkie metody stają się częścią twojej klasy, tak jakbyś je tam umieścił. Zobacz odpowiedź od dylanfm na ok.
method.inspect będzie powiedzieć, czy metoda jest dołączona do Mixin –
Odpowiedź Tobyhede jest niesamowita, ale po prostu wykonałem trochę kopania w irb
i nie ma potrzeby zmniejszania wydajności o #inspect
. Method
klasa
>> Object.new.method(:inspect)
=> #<Method: Object(Kernel)#inspect>
ma kilka przydatnych metod własnych:
>> Object.new.method(:inspect).methods - Object.methods
=> ["owner", "call", "to_proc", "unbind", "arity", "receiver", "[]"]
w szczególności metody #owner
, która zwraca właścicielowi jako właściwego obiektu:
>> [].method(:count).owner
=> Array
>> [].method(:detect).owner
=> Enumerable
niesamowite znalezisko, to na pewno się przyda. –
oczywiście! To bardzo fajnie. –
Słodkie, to wspaniałe – dylanfm