This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is Ruby’s double-colon (::) all about?
pardon for my laziness. I tried to guess. I am not sure what the double '::Logger' does in this case?
https://github.com/wycats/rack-offline/blob/master/lib/rack/offline.rb#L25
it seems like it is initializing the object and assign it on a variable that is not in its scope? line 25 is wrapped by {begin/end} block and gets assigned to #logger
Just like a / in a path defines nested directories, :: accesses nested classes.
And also similarly to a leading /, a leading :: means to start at the the very top of the tree. It starts searching for constants at the global scope.
# Bar declared in global scope
class Bar
end
# Foo declared in global scope
class Foo
# A different class named Bar declared in the scope of Foo, not global
class Bar
end
Bar #=> refers to Foo::Bar, that is class Bar declared within Foo
::Bar #=> refers to outer global scope class named Bar
end
Related
This question already has answers here:
Ruby's double colon (::) operator usage differences
(2 answers)
Closed 6 years ago.
I know that to use class inheritance in Ruby, the following syntax is used:
class MyNewClass < SomeClass
...
end
I also know that nesting in namespaces is identified using :::
class SomeNameSpace::MyNewClass < SomeNameOtherSpace::SomeClass
...
end
However, what does the following syntax mean?
class SomeNameSpace::MyNewClass < ::SomeClass
...
end
I expect that ::SomeClass (so without anything before the ::)is a shorthand for something, but what exactly does it mean?
::SomeClass means SomeClass class from top namespace. :: is specially used to refer the top namespace from deep inside other modules.
I have following file
lib/a/b/c.rb
class a::b::c
def request(env)
#some code here
end
end
Now i am using rubocop style
Style/ClassAndModuleChildren:
Enabled: true
I am getting rubocop offense for this
lib/a/b/c.rb:1:7: C: Use nested module/class definitions instead of compact style.
class a::b::c
When i update my code to following offence get fixed
Style 1
class a
class b
class c
def request(env)
#some code here
end
end
end
end
Style 2
module a
module b
class c
def request(env)
#some code here
end
end
end
end
I think i should use Style 2 as i am using require 'a' in one of my file.
Please let me know how to fix this type & offences and reason for it
The reason this is marked as offence is that constants resolution works lexically, rather than semantically in ruby. This is not intuitive and might lead to some obscure errors (for example if you have two classes with the same name in two different scopes). Compare these two cases:
# Given
module Foo
X = 42
end
# This
module Foo
class Bar
def baz
puts X
end
end
end
# VS
class Foo::Bar
def baz
puts X
end
end
Now when you call:
Foo::Bar.new.baz
In the first case you will get 42, in the second - NameError: uninitialized constant Foo::Bar::X
As for which is the correct way to fix it: Note that using the short syntax will give you an error if Foo doesn't already exist. The answer is - you should use whatever Foo is. If it's a class - use class, if it's a module - module.
Class class is essentially derived from Module class, that’s why Class is a Module with some added functionality; basically the difference is in that Classes might be instantiated.
So, the answer to your question would be: use whatever is more suitable in your case (and by the information given it is impossible to say, what it is.)
require 'a' has nothing to do with the case, since require directive just forces ruby interpreter to load the respective code.
NB: that kind of question is the exact reason why Rubocop complains: it prevents you from using something you are not certain about and forces you to understand, is it in fact Module, or Class by it’s nature.
BTW, since you mentioned you have require 'a' somewhere, it probably means that in this a.rb you have already either module A or class A.
BTW#2 Both class and module names must begin with capital letter, because they are to be constants.
This question already has an answer here:
What does class ClassName < ::OtherClassName do in Ruby?
(1 answer)
Closed 8 years ago.
I saw this line of code.
class ClassName < ::TestUnit::Test::Etc
What does it mean when the nested-constant marker follows the inheritance symbol, like so: < ::SuperClass?
Also, is there a technical name for the :: symbol?
:: is the scope resolution operator. It means "look up the following constant name inside this module". If you omit the module, it is assumed to be Object. So, ::Foo is basically the same as Object::Foo except of course that the enclosing module may define its own Object constant, in which case the second form would look up Foo inside that Object instead of the one you expect it to.
Note that :: can also be used as the message sending operator, i.e. the same way as .: foo::bar is the same as foo.bar. This usage is highly discouraged, though.
What's the best practice for hiding variables in a Ruby file, like the equivalent of a (function() {})() closure in JavaScript?
So if I have a file:
foo = 5
bar = foo * foo
I only want to expose bar, not foo, when someone requires it.
If you have a file containing those two lines and someone requires that file, neither of the two variables will be exposed. Local variables are still local to the file even if they appear at the global scope.
If you want to expose bar, you'll need to turn it into a global variable $bar or, if you don't intend for the variable to change, into a constant Bar. By not doing the same thing to foo it will automatically not be exposed.
You might also consider wrapping the whole thing up in a module or class.
Ruby has scope as many other languages do. Variables are declared the first time they are used and will have scope based on where they are declared. If you use a local to a function:
def do_something
foo = 5
foo * foo
end
puts do_something
It will print 25, but foo will not be available outside of the do_something function.
Is this what you're looking for?
This post talks about Ruby's scoping in more depth Ruby Scoping Rules.
When I set or get instance variables using some name, for example #foo, I can do something like:
instance_variable_set("#foo", some_value)
...
instance_variable_get("#foo")
But often, I use a variable for the method name, which does not include the # prefix, so that I end up doing:
method = :foo
...
instance_variable_set("##{method}", some_value)
...
instance_variable_get("##{method}")
But since all instance variables are prefixed with #, I think it redundant to have to type "##{method}" instead of simply typing method. Why are the methods instance_variable_set and instance_variable_get not designed to accept string/symbol without # as its first argument like this:
method = :foo
...
instance_variable_set(method, some_value)
...
instance_variable_get(method)
where the variable to be actually set will be #foo rather than foo?
Is there any advantage with the way it is?
The reason is, quite simply, that the instance variable is named #foo, not foo. The # is part of the variable name, just as the $ is part of the global variable name $foo.
The reason that # is not necessary when calling attr_accessor and friends is because they define attribute methods, so it makes sense to provide the method names, not the variable names.
Of course there is no technical reason instance_variable_set cannot prepend the # itself. However, the method accepts a symbol that corresponds to the variable name. A symbol by definition represents the identifier with the given name. So the only symbol that corresponds to the instance variable #foo is :#foo. That is why you have to include the #, because we know that :foo does not correspond to any instance variable identifier at all. (And if you supply a string, it will be converted to a symbol internally first.)
Update: In the C Ruby implementation (MRI), there is actually no mention of # anywhere in the code that handles instance variables. Only the parser knows instance variables start with a #. So it seems that separating code parsing from implementation is another possible reason.