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?
:: 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
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: 1
puts Foo::MR_COUNT # this is the local constant: 2
Taken from http://www.tutorialspoint.com/ruby/ruby_operators.htm
:: 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.
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.
Surprisingly, all 10 answers here say the same thing. The '::' is a namespace resolution operator, and yes it is true. But there is one gotcha that you have to realize about the namespace resolution operator when it comes to the constant lookup algorithm. As Matz delineates in his book, 'The Ruby Programming Language', constant lookup has multiple steps. First, it searches a constant in the lexical scope where the constant is referenced. If it does not find the constant within the lexical scope, it then searches the inheritance hierarchy. Because of this constant lookup algorithm, below we get the expected results:
module A
module B
PI = 3.14
module C
class E
PI = 3.15
end
class F < E
def get_pi
puts PI
end
end
end
end
end
f = A::B::C::F.new
f.get_pi
> 3.14
While F inherits from E, the B module is within the lexical scope of F. Consequently, F instances will refer to the constant PI defined in the module B. Now if module B did not define PI, then F instances will refer to the PI constant defined in the superclass E.
But what if we were to use '::' rather than nesting modules? Would we get the same result? No!
By using the namespace resolution operator when defining nested modules, the nested modules and classes are no longer within the lexical scope of their outer modules. As you can see below, PI defined in A::B is not in the lexical scope of A::B::C::D and thus we get uninitialized constant when trying to refer to PI in the get_pi instance method:
module A
end
module A::B
PI = 3.14
end
module A::B::C
class D
def get_pi
puts PI
end
end
end
d = A::B::C::D.new
d.get_pi
NameError: uninitialized constant A::B::C::D::PI
Did you mean? A::B::PI
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.
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
Ruby on rails uses :: for namespace resolution.
class User < ActiveRecord::Base
VIDEOS_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 routed as:
devise_for :users, controllers: {omniauth_callbacks: "users/omniauth_callbacks"}
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
end
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.
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
In simple it is a namespace,
now namespace is container for modules, classes, function and other. and it also help to solve the problem name conflict.
and in ruby you can access namespace by module like
module A
class Article
def Base
end
module B
end
end
so to access the class Article we use A::Article.
and in some cases you see that
A::Article<Application::Base
this mean that the Article class of module A inherit the Base class from Application module.
Reviving this thread a little.
Can we create a 'ruby' name for this operator ::
Surprised that we haven't already since we have splats, spreads, hash rockets etc.
Surely we can come up with something more fun than 'double colon' or 'unary operator'
Thinking
quad dot
four eyes
tetra dot
Nibble (half a byte - 4 bits)
Related
Given I have the following data structure:
module A
module B
module C
class D
end
end
end
end
I want to access it in client code like this:
C::D
rather than
A::B::C::D
One solution would be to define a method in module A like this:
module A
def self.get_d
B::C::D
end
end
A.get_d
But the thing is that C::D is defined in many places already in system. So I need to be backward compatible. How can I address this situation?
There is no such thing as a "nested module". It's just a module that is assigned to a namespaced constant. If you want to assign to a different constant … just assign it to a different constant:
C::D = A::B::C::D
Note: this assumes that a constant named C exists in the current namespace and that it refers to a module or class. However, that assumption is already present in your question.
I understand that instance variables are mean to be states, and constants are meant to be constant. Is there any reason (besides convention) to use a constant instead of an instance variable? Is there a memory/speed advantage to using constants?
There's a few things to consider here:
Will the value change within the life-cycle of an object?
Will you need to override the value in sub-classes?
Do you need to configure the value at run-time?
The best kind of constants are those that don't really change short of updating the software:
class ExampleClass
STATES = %i[
off
on
broken
].freeze
end
Generally you use these constants internally in the class and avoid sharing them. When you share them you're limited in how they're used. For example, if another class referenced ExampleClass::STATES then you can't change that structure without changing other code.
You can make this more abstract by providing an interface:
class ExampleClass
def self.states
STATES
end
end
If you change the structure of that constant in the future you can always preserve the old behaviour:
class ExampleClass
STATES = {
on: 'On',
off: 'Off',
broken: 'Broken'
}.freeze
def self.states
STATES.keys
end
end
When you're talking about instance variables you mean things you can configure:
class ConfigurableClass
INITIAL_STATE_DEFAULT = :off
def self.initial_state
#initial_state || INITIAL_STATE_DEFAULT
end
def self.initial_state=(value)
#initial_state = value ? value.to_sym
end
end
Constants are great in that they're defined once and used for the duration of the process, so technically they're faster. Instance variables are still pretty quick, and are often a necessity as illustrated above.
Constants, unlike instance variables, are global. And they will at least complain if you try to re-assign their value.
While there might be a theoretical difference in memory/speed, it will be irrelevant in practice.
You may not realize this, but classes and modules are considered constants.
pry(main)> Foo
NameError: uninitialized constant Foo
The best advice I can give as to when you should use constants are when they are exactly that, constant. For example, if I was making a scope in rails to find all the of recent Foos for instance, I would create a constant that shows what recent is.
class Foo < ActiveRecord::Base
DAYS_TILL_OLD = 7.days
scope :recent, -> { where "created_at > ?", DateTime.now - DAYS_TILL_OLD }
end
What is the different between the following statements?
#(not working)
File.exists?("path to file")
#(working)
::File.exists?("path to file")
I used above statements in Chef framework of Ruby.
There is another constant named File in the scope where you are using File.exists?("path to file"). But when you use the :: operator, you are telling ruby to find the File constant in Object (Object::File)
Here is possible try to replicate your issue :
Not working :
class Foo< BasicObject
def self.file_size
File.size(__FILE__)
end
end
p Foo.file_size # uninitialized constant Foo::File (NameError)
The reason is File class is available to the top level ( i.e. in the scope of the class Object) and inside any class which is a direct/ indirect subclass of Object. But Foo has no relation with Object, you wouldn't be able to access it inside Foo, if you don't tell it, from where File class ( or constant ) actually accessible.
Working :
class Foo< BasicObject
def self.file_size
::File.size(__FILE__)
end
end
p Foo.file_size # => 132
Although here also, Foo has no relation with Object, but we are explicitly ( by using :: constant scope resolution operator ) telling Ruby that from where we are trying to access the File class ( Remember class(s) are also constant in Ruby) inside Foo class. Thus here is no objection from Ruby.
Check out if such situation is present in your code too.
On a side-note, File.exists? is deprecated - use File.exist?
According to maty, the question should be asked in this way:
"object, do you exist?"
"object.exist?"
Keep this in mind - yes, "if file exist" is not proper english,
but asking it that way would be wrong from the ruby object
point of view.
As for the leading :: - this refers to toplevel scope.
It is not often required, usually only when you have the same name
of a class or a module.
From the Module
Module#append_features(mod) → mod => When this module is included in another, Ruby calls append_features in this module, passing it the receiving module in mod. Ruby’s default implementation is to add the constants, methods, and module variables of this module to mod if this module has not already been added to mod or one of its ancestors.
Module#prepend_features(mod) → mod => When this module is prepended in another, Ruby calls prepend_features in this module, passing it the receiving module in mod. Ruby’s default implementation is to overlay the constants, methods, and module variables of this module to mod if this module has not already been added to mod or one of its ancestors.
Can anyone help me to understand the below questions:
What more features of Module are defined as append and prepend except those default?
How they differ functionally?
When to use append_features and when prepend_features?
what is the difference between two bold lines as above?
What features of Module are defined as append and prepend?
As specified in the text you quoted:
the constants, methods, and module variables
How they differ functionally?
Both add methods of the mixed-in module to the passed module (class). The difference is in the lookup order of these methods, in case that the target class already has them defined:
include behaves as if the target class inherited mixed-in module:
module FooBar
def say
puts "2 - Module"
end
end
class Foo
include FooBar
def say
puts "1 - Implementing Class"
super
end
end
Foo.new.say # =>
# 1 - Implementing Class
# 2 - Module
prepend makes the methods from the mixed in module "stronger" and executes them first:
module FooBar
def say
puts "2 - Module"
super
end
end
class Foo
prepend FooBar
def say
puts "1 - Implementing Class"
end
end
Foo.new.say # =>
# 2 - Module
# 1 - Implementing Class
The example kindly ripped off from here: http://blog.crowdint.com/2012/11/05/3-killer-features-that-are-coming-on-ruby-2-0.html
When to use append_features and when prepend_features?
Use prepend when you want to keep methods of the target module (class) at the end of the method lookup chain.
Some real-world examples can be found by searching SO for ruby, module and prepend:
Overriding method by another defined in module
When monkey patching a method, can you call the overridden method from the new implementation?
Ruby: Module, Mixins and Blocks confusing?
(Note: I am mentioning only methods, as they are easiest to picture when it comes to inheritance and mixing-in, but the same applies to other features.)
I thought to add it as a comment to a good answer which #Mladen Jablanovic has already made but I couldn't due to my low reputation point.
I've found a more concise, clearer and more descriptive answer on a post here - Ruby modules: Include vs Prepend vs Extend and I post it here just in case someone needs it and could get it with less effort.
Direct quotes:
Though include is the most common way of importing external code into a class, Ruby provides also two other ways to achieve that: extend and prepend. However, they don’t have the same behavior at all, and these differences are often misunderstood by Ruby developers.
To understand how to use them, we must first have a deeper look into how Ruby is resolving methods to execute at runtime, using something called the ancestors chain.
When a Ruby class is created, it holds a list of constant names which are its ancestors. They are all the classes that the class inherits from, and the modules they include. For example, by calling ancestors on the String class, we get the list of its ancestors:
String.ancestors
=> [String, Comparable, Object, PP::ObjectMixin, Kernel, BasicObject]
include is the most used and the simplest way of importing module code. When calling it in a class definition, Ruby will insert the module into the ancestors chain of the class, just after its superclass.
Available since Ruby 2, prepend is a bit less known to Rubyists than its two other friends. It actually works like include, except that instead of inserting the module between the class and its superclass in the chain, it will insert it at the bottom of the chain, even before the class itself.
I would suggest reading the post to get a better understanding as it comes with examples.
I'm using a library that lays its library out like this:
module Lib
class A; end
class B; end
...
end
I know that I can use send on an object to "call" a method known only at runtime (e.g., foo.send(:bar, :baz_param=>42). How can I do this at the class level?
In other words, I suspect there's a way to write something like this:
label = :Klass
MyModule.some_method(label).new
that executes, in effect, as:
MyModule::Klass.new
Am I right?
As soon as I posted the question, I had a brainwave:
const_get
Class names are treated as constants, and the method is defined for all modules, too, so the lookup scope can be restricted to that module only. Just remember to get the capitalization right:
MyModule.const_get(:Klass).new # => #<Klass:> #CORRECT
MyModule.const_get(:klass).new # => NameError: wrong constant name