Quel est ce double-colon ::
? Par exemple. Foo::Bar
.
J'ai trouvé un définition :
::
est un opérateur unaire qui permet d'accéder aux constantes, méthodes d'instance et méthodes de classe définies dans une classe ou un module à partir de l'extérieur de la classe ou du module.
A quoi bon scope (private, protected) si vous pouvez simplement utiliser ::
pour exposer quoi que ce soit?
::
est fondamentalement un opérateur de résolution d'espace de noms. Il vous permet d'accéder à des éléments de modules ou à des éléments de niveau de classe. Par exemple, supposons que vous ayez cette configuration:
module SomeModule
module InnerModule
class MyClass
CONSTANT = 4
end
end
end
Vous pouvez accéder à CONSTANT
de l'extérieur du module en tant que SomeModule::InnerModule::MyClass::CONSTANT
.
Cela n'affecte pas les méthodes d'instance définies sur une classe, puisque vous accédez à celles avec une syntaxe différente (le point .
).
Remarque pertinente: Si vous souhaitez revenir à l'espace de noms de niveau supérieur, procédez comme suit: :: SomeModule - Benjamin Oakes
Cet exemple simple l'illustre:
MR_COUNT = 0 # constant defined on main Object class
module Foo
MR_COUNT = 0
::MR_COUNT = 1 # set global count to 1
MR_COUNT = 2 # set local count to 2
end
puts MR_COUNT # this is the global constant
puts Foo::MR_COUNT # this is the local "Foo" constant
Tiré de http://www.tutorialspoint.com/Ruby/ruby_operators.htm
::
Vous permet d'accéder à une constante, à un module ou à une classe définie dans une autre classe ou un autre module. Il est utilisé pour fournir des espaces de noms afin que les noms de méthodes et de classes n'entrent pas en conflit avec d'autres classes d'auteurs différents.
Lorsque vous voyez ActiveRecord::Base
dans Rails, cela signifie que Rails a quelque chose comme:
module ActiveRecord
class Base
end
end
c'est-à-dire une classe appelée Base
à l'intérieur d'un module ActiveRecord
qui est ensuite référencé comme ActiveRecord::Base
(vous pouvez le trouver dans la source Rails dans activerecord-nnn/lib/active_record /base.rb)
Une utilisation courante de :: est d’accéder aux constantes définies dans les modules, par exemple.
module Math
PI = 3.141 # ...
end
puts Math::PI
L'opérateur ::
ne vous permet pas de contourner la visibilité des méthodes marquées comme privées ou protégées.
À quoi sert scope (privé, protégé) si vous pouvez simplement utiliser :: pour exposer quoi que ce soit?
En Ruby, tout est exposé et tout peut être modifié de n'importe où.
Si vous êtes préoccupé par le fait que les classes peuvent être modifiées en dehors de la "définition de classe", alors Ruby ne vous convient probablement pas.
D'un autre côté, si vous êtes frustré par le verrouillage des classes de Java, alors Ruby est probablement ce que vous recherchez.
Non, il ne s'agit pas d'accéder à toutes les méthodes, il s'agit d'un opérateur "résolution", c'est-à-dire que vous l'utilisez pour résoudre la portée (ou l'emplacement que vous pouvez dire) d'un symbole constant/statique.
Par exemple, dans le premier de votre ligne, Rails l'utilise pour rechercher la classe Base à l'intérieur d'ActiveRecord.Module, dans le second, il est utilisé pour localiser la méthode de classe (statique) de la classe Routes, etc. , etc.
Il n'est pas utilisé pour exposer quoi que ce soit, il est utilisé pour "localiser" des choses autour de votre portée.
En ajoutant aux réponses précédentes, il est valide Ruby d'utiliser ::
pour accéder aux méthodes d'instance. Tous les éléments suivants sont valables:
MyClass::new::instance_method
MyClass::new.instance_method
MyClass.new::instance_method
MyClass.new.instance_method
Selon les meilleures pratiques, je crois que seul le dernier est recommandé.
Il s’agit d’empêcher que les définitions ne se heurtent à d’autres codes liés à votre projet. Cela signifie que vous pouvez garder les choses séparées.
Par exemple, vous pouvez avoir une méthode appelée "run" dans votre code et vous pourrez toujours appeler votre méthode plutôt que la méthode "run" définie dans une autre bibliothèque que vous avez liée.
Étonnamment, les 10 réponses ici disent la même chose. Le '::' est un opérateur de résolution d'espace de noms, et c'est vrai. Mais il faut comprendre l’opérateur de résolution d’espace de nommage algorithme de recherche constante. Comme Matz le décrit dans son livre, 'Le langage de programmation Ruby _', la recherche constante comporte plusieurs étapes. Premièrement, il recherche une constante dans le portée lexicale où la constante est référencée. S'il ne trouve pas la constante dans la portée lexicale, il recherche alors hiérarchie d'héritage. En raison de cet algorithme de recherche constante, nous obtenons ci-dessous les résultats attendus:
module A
module B
PI = 3.14
module C
class E
PI = 3.15
end
class F < E
def get_pi
puts PI
end
end
end
end
end
f = A::B::C::F.new
f.get_pi
> 3.14
Tandis que F hérite de E, le module B est dans la portée lexicale de F. Par conséquent, les instances F feront référence à la constante PI définie dans le module B. Maintenant, si le module B n'a pas défini PI, les instances F font référence à PI constante définie dans la superclasse E.
Mais que se passerait-il si nous utilisions '::' plutôt que des modules d'imbrication? Aurions-nous le même résultat? Non!
En utilisant l'opérateur de résolution d'espace de noms lors de la définition de modules imbriqués, les modules et les classes imbriquées ne font plus partie de la portée lexicale de leurs modules externes. Comme vous pouvez le voir ci-dessous, PI défini dans A :: B n'est pas dans la portée lexicale de A :: B :: C :: D et nous obtenons donc une constante non initialisée lorsque nous essayons de faire référence à PI dans la méthode d'instance get_pi:
module A
end
module A::B
PI = 3.14
end
module A::B::C
class D
def get_pi
puts PI
end
end
end
d = A::B::C::D.new
d.get_pi
NameError: uninitialized constant A::B::C::D::PI
Did you mean? A::B::PI
Ruby on Rails utilise :: pour la résolution de l'espace de noms.
class User < ActiveRecord::Base
VIDES_COUNT = 10
Languages = { "English" => "en", "Spanish" => "es", "Mandarin Chinese" => "cn"}
end
Pour l'utiliser :
User::VIDEOS_COUNT
User::Languages
User::Languages.values_at("Spanish") => "en"
En outre, une autre utilisation est: lors de l'utilisation d'itinéraires imbriqués
OmniauthCallbacksController
est défini sous utilisateurs.
et la route est comme:
devise_for :users, controllers: {omniauth_callbacks: "users/omniauth_callbacks"}
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
end
module Amimal
module Herbivorous
EATER="plants"
end
end
Amimal::Herbivorous::EATER => "plants"
:: Est utilisé pour créer une portée. Pour accéder à Constant EATER à partir de 2 modules, nous devons définir la portée des modules afin d’atteindre la