O que é esse cólon duplo ::
? Por exemplo Foo::Bar
.
Eu encontrei uma definição :
O
::
é um operador unário que permite: constantes, métodos de instância e métodos de classe definidos em uma classe ou módulo, sejam acessados de qualquer lugar fora da classe ou módulo.
Qual a utilidade do escopo (privado, protegido) se você puder apenas usar ::
para expor alguma coisa?
Respostas:
::
é basicamente um operador de resolução de espaço para nome. Permite acessar itens em módulos ou itens em nível de classe nas classes. Por exemplo, digamos que você tenha esta configuração:Você pode acessar
CONSTANT
de fora do módulo comoSomeModule::InnerModule::MyClass::CONSTANT
.Isso não afeta os métodos de instância definidos em uma classe, pois você acessa aqueles com uma sintaxe diferente (o ponto
.
).Nota relevante: Se você deseja retornar ao namespace de nível superior, faça o seguinte: :: SomeModule - Benjamin Oakes
fonte
::
para resolução de namespace, comostd::cout << "Hello World!";
::SomeModule
Este exemplo simples ilustra isso:
Retirado de http://www.tutorialspoint.com/ruby/ruby_operators.htm
fonte
::
Permite acessar uma constante, módulo ou classe definida dentro de outra classe ou módulo. É usado para fornecer espaços de nomes para que os nomes de métodos e classes não entrem em conflito com outras classes por autores diferentes.Quando você vê
ActiveRecord::Base
no Rails, significa que o Rails tem algo comoou seja, uma classe chamada
Base
dentro de um móduloActiveRecord
que é referenciada comoActiveRecord::Base
(você pode encontrar isso na fonte Rails em activerecord-nnn / lib / active_record / base.rb)Um uso comum de :: é acessar constantes definidas em módulos, por exemplo
O
::
operador não permite ignorar a visibilidade dos métodos marcados como privados ou protegidos.fonte
class MyClass < ActiveRecord::Base
, isso significa que o MyClass herda apenas métodos da base da classe e não nada dentro do módulo ActiveRecord?class Foo; Baz = 42; def self.Baz; "Baz method!"; end; end
(perfeitamente válido)Foo::Baz # => 42
eFoo.Baz # => "Baz method!"
. Observe queFoo::Baz()
(com parênteses) também chamaria o método.No Ruby, tudo é exposto e tudo pode ser modificado de qualquer outro lugar.
Se você está preocupado com o fato de que as classes podem ser alteradas de fora da "definição de classe", Ruby provavelmente não é para você.
Por outro lado, se você está frustrado com o bloqueio das classes de Java, Ruby é provavelmente o que você está procurando.
fonte
attr_accessor
apenas cria métodos que modificam a variável. (Então, novamente háinstance_eval
)instance_eval
. Mas há tambéminstance_variable_get
einstance_variable_set
. Ruby é dinâmico demais para restrições.Adicionando respostas anteriores, é válido usar Ruby
::
para acessar métodos de instância. Todos os seguintes são válidos:De acordo com as práticas recomendadas, acredito que apenas a última seja recomendada.
fonte
Não, não é para acessar todos os métodos, é um operador de "resolução", ou seja, você o utiliza para resolver o escopo (ou o local que você pode dizer) de um símbolo constante / estático.
Por exemplo, no primeiro da sua linha, o Rails o utiliza para encontrar a classe Base dentro do ActiveRecord.Module, no segundo é usado para localizar o método da classe (estático) da classe Routes, etc.
Não é usado para expor nada, é usado para "localizar" coisas em torno de seus escopos.
http://en.wikipedia.org/wiki/Scope_resolution_operator
fonte
Surpreendentemente, todas as 10 respostas aqui dizem a mesma coisa. O '::' é um operador de resolução de espaço para nome e sim, é verdade. Mas há um problema que você precisa entender sobre o operador de resolução do espaço para nome quando se trata do algoritmo de pesquisa constante . Como Matz delineia em seu livro 'The Ruby Programming Language', a pesquisa constante tem várias etapas. Primeiro, ele pesquisa uma constante no escopo lexical onde a constante é referenciada. Se não encontrar a constante no escopo lexical, ela procurará na hierarquia de herança . Devido a esse algoritmo de pesquisa constante, abaixo obtemos os resultados esperados:
Enquanto F herda de E, o módulo B está dentro do escopo lexical de F. Consequentemente, as instâncias F se referem à PI constante definida no módulo B. Agora, se o módulo B não definiu PI, as instâncias F se referem ao PI constante definida na superclasse E.
Mas e se usássemos '::' em vez de aninhar módulos? Teríamos o mesmo resultado? Não!
Ao usar o operador de resolução de espaço para nome ao definir módulos aninhados, os módulos e as classes aninhadas não estão mais dentro do escopo lexical de seus módulos externos. Como você pode ver abaixo, o PI definido em A :: B não está no escopo lexical de A :: B :: C :: D e, portanto, obtemos constante não inicializada ao tentar fazer referência ao PI no método de instância get_pi:
fonte
Trata-se de impedir que as definições colidam com outro código vinculado ao seu projeto. Isso significa que você pode manter as coisas separadas.
Por exemplo, você pode ter um método chamado "run" em seu código e ainda poderá chamar seu método em vez do método "run" que foi definido em alguma outra biblioteca na qual você vinculou.
fonte
:: É usado para criar um escopo. Para acessar o Constant EATER a partir de 2 módulos, precisamos definir o escopo dos módulos para alcançar a constante
fonte
Ruby on rails usa
::
para resolução de namespace.Para usá-lo :
Além disso, outro uso é: Ao usar rotas aninhadas
OmniauthCallbacksController
é definido em usuários.E roteado como:
fonte