Ruby: que fait :: prefix?

89

Je lisais la source d' Artifice et j'ai vu:

module Artifice
  NET_HTTP = ::Net::HTTP
  # ...
end

ligne: https://github.com/wycats/artifice/blob/master/lib/artifice.rb#L6

Pourquoi ne pas simplement faire Net::HTTPau lieu de ::Net::HTTP, c'est-à-dire, qu'est-ce que cela signifie lorsque vous utilisez ::comme préfixe?

ma11hew28
la source
15
J'ai cherché ce sujet en utilisant l'expression "deux-points principaux" et je ne l'ai pas trouvé au départ; j'espère que ce commentaire changera cela. :)
Nathan Long
@NathanLong Idée intéressante. Cela a-t-il fonctionné? Veuillez faire un rapport.
Darth Egregious
1
@NathanLong Ça a marché!
coreyward

Réponses:

220

Le ::est l'opérateur de résolution de portée. Il détermine la portée sous laquelle un module peut être trouvé. Par exemple:

module Music
  module Record
    # perhaps a copy of Abbey Road by The Beatles?
  end

  module EightTrack
    # like Gloria Gaynor, they will survive!
  end
end

module Record
  # for adding an item to the database
end

Pour accéder Music::Recordde l'extérieur de Musicvous utilisezMusic::Record .

Pour référencer Music::Recordde Music::EightTrackvous pouvez simplement utiliser Recordcar il est défini dans la même portée (celle de Music).

Cependant, pour accéder au Recordmodule responsable de l'interfaçage avec votre base de données, Music::EightTrackvous ne pouvez pas simplement l'utiliser Recordparce que Ruby pense que vous le souhaitez Music::Record. C'est lorsque vous utilisez l'opérateur de résolution de portée comme préfixe, en précisant la portée globale / main: ::Record.

coreyward
la source
12
Oui, réponse très complète. Merci!
ma11hew28
11
Excellente réponse. Pour votre information, ne vous inquiétez pas des votes négatifs. Il y a des choses beaucoup plus significatives dans la vie.
Darth Egregious
16
module A
  def self.method; "Outer"; end
end
module B
  module A
    def self.method; "Inner"; end
  end
  A.method   # => "Inner"
  ::A.method # => "Outer"
end

Dans le cas spécifique d'Artifice, à la ligne 41 du fichier que vous avez montré est défini un Netmodule interne . Pour garder l'accès au Netmodule externe , il utilise ::Net.

Guilherme Bernal
la source