I know ::
allows us to access items in modules, or class-level items in classes, but what does only ::String
mean??
What is the difference betwee开发者_开发问答n String =="hi".class
and ::String=="hi".class
??
The class is defined as below.
class String
end
::String
references the top level String
class. String
references either a string in the current namespace or namespaces above.
Take a look at the following code:
module MyModule
class String
def initialize(s); end
def split(operator=nil)
puts "This string doesn't split"
end
end
class SomeClass
def bar
s = String.new("foo:bar")
s.split(":")
end
def foo
s = ::String.new("foo:bar")
s.split(":")
end
end
end
sc = MyModule::SomeClass.new
sc.foo
=> ["foo", "bar"]
sc.bar
This string doesn't split
=> nil
Since String
exists in both the top level namespace and in the module MyModule
, you need to explicitly reference the top level string by using the top level namespace ::
.
In the specific case of String
vs ::String
, the answer is: there will approximately never be a difference.
In the general case of constant X
vs ::X
, sure. X
might be A::B::C::X
or A::B::X
or just X
, but ::X
is always "just X
", whereas plain "X
" could be any of them.
String
is quite important, though, so no one will redefine it accidentally. In the unlikely case that an inner class or module named String
is defined, it is most likely the intention that contained code use it rather than String
, err, sorry, ::String
.
Update: I should add that simply seeing class String; end
does not define class String
in the sense that I think you mean. In Ruby, classes can be reopened. The class
keyword may or may not introduce a new class. It might just be adding behavior to an existing one, and if there is nothing inside, then it's just a no-op. The old class behavior is still there,
This means "access String constant from top level namespace".
Class String might be defined in some module - this will tell the interpreter to access the class in top level namespace.
精彩评论