可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
What is this double-colon ::
? E.g. Foo::Bar
.
I found a definition:
The ::
is a unary operator that allows: constants, instance methods and class methods defined within a class or module, to be accessed from anywhere outside the class or module.
What good is scope (private, protected) if you can just use ::
to expose anything?
回答1:
::
is basically a namespace resolution operator. It allows you to access items in modules, or class-level items in classes. For example, say you had this setup:
module SomeModule
module InnerModule
class MyClass
CONSTANT = 4
end
end
end
You could access CONSTANT
from outside the module as SomeModule::InnerModule::MyClass::CONSTANT
.
It doesn\'t affect instance methods defined on a class, since you access those with a different syntax (the dot .
).
Relevant note: If you want to go back to the top-level namespace, do this: ::SomeModule – Benjamin Oakes
回答2:
This simple example illustrates it:
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
Taken from http://www.tutorialspoint.com/ruby/ruby_operators.htm
回答3:
::
Lets you access a constant, module, or class defined inside another class or module. It is used to provide namespaces so that method and class names don\'t conflict with other classes by different authors.
When you see ActiveRecord::Base
in Rails it means that Rails has something like
module ActiveRecord
class Base
end
end
i.e. a class called Base
inside a module ActiveRecord
which is then referenced as ActiveRecord::Base
(you can find this in the Rails source in activerecord-n.n.n/lib/active_record/base.rb)
A common use of :: is to access constants defined in modules e.g.
module Math
PI = 3.141 # ...
end
puts Math::PI
The ::
operator does not allow you to bypass visibility of methods marked private or protected.
回答4:
What good is scope (private, protected) if you can just use :: to expose anything?
In Ruby, everything is exposed and everything can be modified from anywhere else.
If you\'re worried about the fact that classes can be changed from outside the \"class definition\", then Ruby probably isn\'t for you.
On the other hand, if you\'re frustrated by Java\'s classes being locked down, then Ruby is probably what you\'re looking for.
回答5:
No, it is not to access every method, it is a \"resolution\" operator, that is, you use it to resolve the scope (or location you can say) of a constant/static symbol.
For example in the first of your line, Rails use it to find the Base class inside the ActiveRecord.Module, in your second one it is used to locate the class method (static) of the Routes class, etc, etc.
It is not used to expose anything, its used to \"locate\" stuff around your scopes.
http://en.wikipedia.org/wiki/Scope_resolution_operator
回答6:
Adding to previous answers, it is valid Ruby to use ::
to access instance methods. All the following are valid:
MyClass::new::instance_method
MyClass::new.instance_method
MyClass.new::instance_method
MyClass.new.instance_method
As per best practices I believe only the last one is recommended.
回答7:
It is all about preventing definitions from clashing with other code linked in to your project. It means you can keep things separate.
For example you can have one method called \"run\" in your code and you will still be able to call your method rather than the \"run\" method that has been defined in some other library that you have linked in.
回答8:
Ruby on rails uses :: for namespace resolution.
class User < ActiveRecord::Base
VIDES_COUNT = 10
Languages = { \"English\" => \"en\", \"Spanish\" => \"es\", \"Mandarin Chinese\" => \"cn\"}
end
To use it :
User::VIDEOS_COUNT
User::Languages
User::Languages.values_at(\"Spanish\") => \"en\"
Also, other usage is : When using nested routes
OmniauthCallbacksController
is defined under users.
and route is like :
devise_for :users, controllers: {omniauth_callbacks: \"users/omniauth_callbacks\"}
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
end
回答9:
module Amimal
module Herbivorous
EATER=\"plants\"
end
end
Amimal::Herbivorous::EATER => \"plants\"
:: Is used to create a scope . In order to access Constant EATER from 2 modules we need to scope the modules to reach up to the constant