Qu'est-ce que le double-côlon de Ruby?

Qu'est-ce que ce double-côlon :: ? Par exemple: Foo::Bar .

j'ai trouvé un définition :

le :: est un opérateur unaire qui permet: les constantes, les méthodes d'instance et les méthodes de classe définies dans une classe ou un module, d'être accessibles à partir de n'importe où en dehors de la classe ou du module.

quel bien est scope (privé, protégé) si vous pouvez juste utiliser :: pour exposer quoi que ce soit?

369
demandé sur sawa 2010-06-10 00:03:36

9 réponses

:: est fondamentalement un opérateur de résolution d'espace de noms. Il vous permet d'accéder à des éléments dans les modules, ou des éléments de niveau de classe dans les classes. Par exemple, si vous aviez cette configuration:

module SomeModule
    module InnerModule
        class MyClass
            CONSTANT = 4
        end
    end
end

vous pouvez accéder à CONSTANT depuis l'extérieur du module comme 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 . ).

Note pertinente: Si vous voulez revenir à l'espace de noms de haut niveau, Faites ceci:: SomeModule - Benjamin Oakes

323
répondu mipadi 2017-02-09 18:30:07

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

101
répondu Nader 2011-03-15 21:47:12

:: vous Permet d'accéder à une constante, un module ou une classe définie à l'intérieur d'une autre classe ou d'un module. Il est utilisé pour fournir des espaces de noms de sorte que les noms de méthodes et de classes n'entrent pas en conflit avec d'autres classes par différents auteurs.

quand vous voyez ActiveRecord::Base dans les Rails cela signifie que les Rails ont 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 alors référencé comme ActiveRecord::Base (vous pouvez trouver ceci dans la source de Rails dans activerecord-N. N. n/lib/active_record / base.rb) 151990920"

une utilisation courante de:: est d'accéder à des constantes définies dans des modules, p.ex.

module Math
  PI = 3.141 # ...
end

puts Math::PI

Le :: opérateur ne vous permet pas de contourner la visibilité des méthodes marqué privés ou protégés.

68
répondu mikej 2010-06-09 20:22:01

à quoi sert scope (privé, protégé) si vous pouvez simplement utiliser :: exposer quoi que ce soit?

en Ruby, tout est exposé et tout peut être modifié de n'importe où ailleurs.

si vous êtes inquiet du fait que les classes peuvent être changées en dehors de la" définition de classe", alors Ruby n'est probablement pas pour vous.

d'un autre côté, si vous êtes frustré par les classes de Java étant verrouillé, puis Ruby est probablement ce que vous cherchez.

24
répondu yfeldblum 2010-06-09 20:17:23

non, ce n'est pas pour accéder à toutes les méthodes, c'est un opérateur de" 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 la première de votre ligne, les Rails l'utilisent pour trouver la classe de Base à l'intérieur du ActiveRecord.Module, dans votre second il est utilisé pour localiser la méthode de classe (statique) des Itinéraires de classe, etc, etc.

Il n'est pas utilisé pour exposer quoi que ce soit, il est utilisé pour "localiser" trucs autour de votre étendues.

http://en.wikipedia.org/wiki/Scope_resolution_operator

11
répondu Francisco Soto 2010-06-09 20:17:54

il s'agit d'éviter que les définitions entrent en conflit avec 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 " qui a été définie dans une autre bibliothèque que vous avez liée.

4
répondu Mongus Pong 2010-06-09 20:13:40

Ajouter 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 pratiques exemplaires, je crois que seule la dernière est recommandée.

4
répondu Yuri Ghensev 2017-06-09 03:46:47
module Amimal
      module Herbivorous
            EATER="plants" 
      end
end

Amimal::Herbivorous::EATER => "plants"

:: est utilisé pour créer une portée . Afin d'accéder à Constant EATER à partir de 2 modules, nous avons besoin de définir la portée des modules pour atteindre la constante

2
répondu Francesca Rodricks 2015-04-09 04:31:55

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"

également, une autre utilisation est: lors de l'utilisation de routes imbriquées

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
2
répondu Pankhuri 2015-06-30 18:53:05