web-dev-qa-db-fra.com

ruby super mot clé

D'après ce que je comprends, le mot clé super invoque une méthode portant le même nom que la méthode actuelle dans la superclasse de la classe actuelle. Ci-dessous dans la méthode autoload, il y a un appel à super. Je voudrais savoir dans quelle superclasse je trouverais une méthode du 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 branche principale Rails. Merci beaucoup.

57
user290870

L'exemple fourni dans les documents Ruby pour le mot clé 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

Inspecter les ancêtres

puts Car.ancestors.inspect

# Output
# [Car, Vehicle, Vehicular, Object, Kernel, BasicObject]

Notez l'inclusion de l'objet VehicularModule!

45
maček

Cochez objRef.class.ancestors Ou ClassName.ancestors Pour connaître la chaîne d'héritage. Si la super classe ne contient pas la méthode, tous les modules inclus par la super classe sont vérifiés (le dernier inclus est vérifié en premier). Si aucun match, 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")} pour vous concentrer sur la méthode appelée.

(Remarque: le code ci-dessus est Ruby 1.8. Dans 1.9 methods renvoie des symboles au lieu de chaînes. Vous devez donc faire un m.to_s.include?(...))

15
Gishu

Utilisez Pry

Insérez un binding.pry appelez juste avant d'utiliser super, puis appelez show-source -s (-s signifie superclass) pour afficher la méthode de la 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) #<B>: 0> show-source -s

From: (pry) @ line 2:
Number of lines: 3
Owner: A   # <--see owner here (i.e superclass)
Visibility: public

def hello
  puts "hi"
end
[2] (pry) #<B>: 0>    
14
horseyguy

Le mot clé super vérifie tout le long de l'arbre d'ascendance pour trouver la méthode héritée.

Effectuez une recherche sur l'ensemble de la branche principale Rails. Vous ne trouverez qu'une seule def autoload qui est exactement celui que vous regardez dans active_support/lib/active_support/dependencies/autoload.rb.

La méthode en cours de substitution est Ruby native. C'est Module#autoload

5
maček

J'ai ajouté cette méthode pour trouver le propriétaire d'une méthode dans mon .irbrc, quelqu'un voit-il une meilleure façon de le faire, en particulier dans la gestion des méthodes singleton où la superclasse de la classe singleton est la classe singleton de la superclasse?

  class Object
    def find_method(method_string)
        if klasses = self.class.ancestors.select { |a| a if a.methods.include? method_string }
          puts "class method in #{klasses.join(',')}" unless klasses.empty?
        end
        if klasses = self.class.ancestors.select { |a| a if a.instance_methods.include? method_string }
          puts "instance method in #{klasses.join(',')}" unless klasses.empty?
        end
      rescue
        raise "owning class not found"
    end
  end
2
Eric Steen

La méthode de superclasse appropriée est probablement Module # autoload .

1
Greg Campbell