D’après ce que j’ai compris, super
mot super
clé invoque une méthode avec le même nom que la méthode actuelle dans la super-classe de la classe actuelle. Ci-dessous, dans la méthode de autoload
, il y a un appel à super
. Je voudrais savoir dans quelle superclasse je trouverais une méthode avec le même nom ou que fait l’appel à super
ici
module ActiveSupport module Autoload ... def autoload(const_name, path = @@at_path) full = [self.name, @@under_path, const_name.to_s, path].compact.join("::") location = path || Inflector.underscore(full) if @@eager_autoload @@autoloads[const_name] = location end super const_name, location end .... end end module ActiveRecord extend ActiveSupport::Autoload ... autoload :TestCase autoload :TestFixtures, 'active_record/fixtures' end
Ce code provient de la twig principale des rails. Merci beaucoup.
super
: module Vehicular def move_forward(n) @position += n end end class Vehicle include Vehicular # Adds Vehicular to the lookup path end class Car < Vehicle def move_forward(n) puts "Vrooom!" super # Calls Vehicular#move_forward end end
puts Car.ancestors.inspect # Output # [Car, Vehicle, Vehicular, Object, Kernel, BasicObject]
Notez l'inclusion de l'object Module
Vehicular
!
Vérifiez objRef.class.ancestors
ou ClassName.ancestors
pour connaître la chaîne d’inheritance. Si la super-classe ne contient pas la méthode, tous les modules inclus par la super-classe sont vérifiés (dernier inclus vérifié en premier). S’il n’y a pas de correspondance, alors il monte d’un niveau à la classe des grands-parents et ainsi de suite.
Vous pouvez utiliser la liste des ancêtres, puis appeler AncestorClass.methods.select{|m| m.include?("auto_load")}
AncestorClass.methods.select{|m| m.include?("auto_load")}
pour AncestorClass.methods.select{|m| m.include?("auto_load")}
la méthode appelée.
(Remarque: le code ci-dessus est Ruby 1.8. Dans les methods
1.9 methods
retourne des symboles au lieu de chaînes. Vous devrez donc faire un m.to_s.include?(...
)
Utilisez Pry
Insérez un appel binding.pry
juste avant d’utiliser super
, puis appelez show-source -s
( -s
signifie superclass
) pour afficher la méthode superclasse et savoir où elle est définie:
class A def hello puts "hi" end end class B < A def hello binding.pry super end end b = B.new b.hello From: (pry) @ line 7 B#hello: 7: def hello => 8: binding.pry 9: super 10: end [1] (pry) #: 0> show-source -s From: (pry) @ line 2: Number of lines: 3 Owner: A # <--see owner here (ie superclass) Visibility: public def hello puts "hi" end [2] (pry) #: 0>
Le mot super
clé super
vérifie complètement l’arbre de l’ascendance pour trouver la méthode héritée.
Effectuez une recherche sur l’ensemble de la twig principale des rails. Vous ne trouverez qu’un seul def autoload
qui est exactement celui que vous active_support/lib/active_support/dependencies/autoload.rb
dans active_support/lib/active_support/dependencies/autoload.rb
.
La méthode en cours de remplacement est la méthode Ruby native. C’est le Module#autoload
J’ai ajouté cette méthode pour trouver le propriétaire d’une méthode dans mon fichier .irbrc. Y a-t-il un meilleur moyen de le faire, en particulier en ce qui concerne les méthodes singleton où la super classe de la classe singleton est la classe singleton?
class Object def find_method(method_ssortingng) if klasses = self.class.ancestors.select { |a| a if a.methods.include? method_ssortingng } puts "class method in #{klasses.join(',')}" unless klasses.empty? end if klasses = self.class.ancestors.select { |a| a if a.instance_methods.include? method_ssortingng } puts "instance method in #{klasses.join(',')}" unless klasses.empty? end rescue raise "owning class not found" end end
La méthode de super-classe appropriée est probablement le module # autoload .