2011-01-28 3 views
5

J'ai un code hérité que je modifie. Cependant, je vois quelque chose d'étrange (pour moi).Qu'est-ce que :: faire?

Je vois un code comme ceci:

::User.find_by_email(params[:user][:email]).update_attributes(:mag => 1) 

Je ne l'ai jamais vu quelque chose comme ça (je suis nouveau à Ruby on Rails). Qu'est-ce que cela fait et pourquoi mon User.find_by_email(params[:user][:email]).update_attributes(:mag => 1) ne fonctionne-t-il pas? L'erreur indique quelque chose à propos de la constante User. J'utilise Rails 2.3.5 si cela peut aider.

Répondre

17

:: est un opérateur de résolution de portée, cela signifie effectivement « dans l'espace », donc ActiveRecord::Base signifie « Base, dans l'espace de noms ActiveRecord »

Une constante être résolue en dehors de tout espace de noms signifie exactement ce que cela ressemble - une constante qui n'est dans aucun espace de noms.

Il est utilisé dans des endroits où le code peut être ambigu sans elle:

module Document 
    class Table # Represents a data table 

    def setup 
     Table # Refers to the Document::Table class 
     ::Table # Refers to the furniture class 
    end 

    end 
end 

class Table # Represents furniture 
end 
2

Vous pourriez trouver un chef de file ici: What is Ruby's double-colon `::`?

+1

qui explique ce que le :: fait, mais pas ce qu'est un :: sans identifiant en face ne. :) –

+1

Assez vrai. Je n'utilise pas Ruby, mais l'opérateur '::' semble être un opérateur de résolution d'oscilloscope. Je suppose que ':: User' simpy signifie l'identifiant global de l'utilisateur dans le module courant. Quelqu'un peut-il confirmer? –

+0

Je peux. Vois ma réponse. :) –

4

Il veille à charger le modèle de l'utilisateur dans l'espace de noms global. Imaginez que vous ayez un modèle User global et un autre modèle User dans votre module actuel (Foo :: User). En appelant :: User vous assurez-vous d'obtenir le global.

+0

Même compréhension ici – YOU

2

Ruby utilise (entre autres) une portée lexicale pour trouver des noms constants. Par exemple, si vous avez ce code:

module Foo 
    class Bar 
    end 

    def self.get_bar 
    Bar.new 
    end 
end 

class Bar 
end 

Les Foo.get_bar renvoie une instance de Foo::Bar. Mais si nous mettons :: devant un nom constant, cela force Ruby à ne regarder que dans le niveau supérieur pour la constante. Donc, ::Bar fait toujours référence à la classe Bar de niveau supérieur.

Vous rencontrerez des situations dans Ruby où la façon dont votre code est exécuté vous obligera à utiliser ces références constantes «absolues» pour accéder à la classe que vous voulez.

1

L'opérateur "::" est utilisé pour accéder aux classes à l'intérieur des modules. De cette façon, vous pouvez également accéder indirectement aux méthodes. Exemple:

module Mathematics 
    class Adder 
     def Adder.add(operand_one, operand_two) 
      return operand_one + operand_two 
     end 
    end 
end 

Vous accédez ainsi:

puts “2 + 3 = “ + Mathematics::Adder.add(2, 3).to_s