Ruby: what does :: prefix do?
The ::
is the scope resolution operator. What it does is determines what scope a module can be found under. For example:
module Music
module Record
# perhaps a copy of Abbey Road by The Beatles?
end
module EightTrack
# like Gloria Gaynor, they will survive!
end
end
module Record
# for adding an item to the database
end
To access Music::Record
from outside of Music
you would use Music::Record
.
To reference Music::Record
from Music::EightTrack
you could simply use Record
because it's defined in the same scope (that of Music
).
However, to access the Record
module responsible for interfacing with your database from Music::EightTrack
you can't just use Record
because Ruby thinks you want Music::Record
. That's when you would use the scope resolution operator as a prefix, specifying the global/main scope: ::Record
.
Why prefix a method with self
Within the context of a module, declaring a method with self
as a prefix makes it a module method, one that can be called without having to include
or extend
with the module.
If you'd like to have mix-in methods, which is the default, and module methods, which requires the self
prefix, you can do this:
module Math
# Define a mix-in method
def square(x)
x ** 2
end
# Make all mix-in methods available directly
extend self
end
That should have the effect of making these methods usable by calling Math.square
directly.
What does -@ operator do in Ruby?
-@
and +@
are simply the method names for unary -
and +
. If you want to redefine them, invoke them as methods, etc., that's how you need to refer to them to distinguish them from binary -
and +
.
Why do we prefix class variables with @@ in ruby?
if the variable is created inline with the class definition, self is defined as Test, and the variable is a class variable correct?
No. It is an instance variable of a class. It is not a class variable.
Instance variable is visible only to that instance. Class variable is visible to the class, other ancestry classes, and their instances.
@var
defined in line 2 is defined forTest
(which is an instance ofClass
class). It is not visible to ancestry classes ofTest
, nor to instances of them.@@var
is defined forTest
as well as for its ancestry classes, as well as for their instances. They all share the same@@var
.@var
defined in line 6 is defined for a certain instance ofTest
(which is not by itselfTest
). It is not visible toTest
, nor to other instances ofTest
.
What does the (unary) * operator do in this Ruby code?
The *
is the splat operator.
It expands an Array
into a list of arguments, in this case a list of arguments to the Hash.[]
method. (To be more precise, it expands any object that responds to to_ary
/to_a
, or to_a
in Ruby 1.9.)
To illustrate, the following two statements are equal:
method arg1, arg2, arg3
method *[arg1, arg2, arg3]
It can also be used in a different context, to catch all remaining method arguments in a method definition. In that case, it does not expand, but combine:
def method2(*args) # args will hold Array of all arguments
end
Some more detailed information here.
What is Ruby's double-colon `::`?
::
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
Could you explain what's !! do?
It is used to make sure its the boolean type.
Explanation more detailed
Eg:
!!active
=> true
active = false
=> false
!!active
=> false
active = nil
=> nil
!!active
=> false
Dynamically generate prefixes for method names
Try this,
class Module
def with_prefix(prefix, &block)
m = Module.new
m.instance_eval(&block)
m.methods(false).each do |name|
define_method "#{prefix}_#{name}", &m.method(name)
module_function "#{prefix}_#{name}" unless self.is_a?(Class)
end
end
end
class A
with_prefix :pref do
with_prefix :and do
def foo
puts "foo called"
end
def bar
puts "bar called"
end
end
end
end
A.new.pref_and_foo
A.new.pref_and_bar
How does this work?
- We define a new function
with_prefix
on the superclass of all classes - This function takes a name and a block
- Evaluate the block in the context of an anonymous module.
- This executes the
def
statements on the anonymous module rather than the class - Enumerate over all functions of that module
- Create prefixed methods for each of those functions
how to set up and use a Rails routes prefix
Paths
I'm not sure why it's called prefix
- it should be called path helper
:
The bottom line is when you call helpers like link_to
or form_tag
etc - they will require paths
to populate different actions in your app's routing structure.
As Rails favours convention over configuration
& DRY programming, meaning if you can reference these path helpers
over using standard urls
, it will allow you to make one reference & chance the route as required
EG
Calling articles_path
is far more powerful than referencing /articles
every time
Routes
To answer your question properly, you will need to appreciate Rails uses resourceful
routing - basically meaning that every route
helper you create should be defined around any resource in your application
Due to the MVC structure of Rails, these resources will typically be defined by the controllers
you use:
#config/routes.rb
resources :articles #-> articles_path etc
You should always reference your resources as they are (in your case articles
).
To customize the path helper, you'll need to change the reference in the routes file, like this:
#config/routes.rb
resources :articles, as: :document, path: "document" #-> domain.com/documents
This allows you to define custom routes / path helpers, allowing you to call those as you wish
Related Topics
Unresolved Specs During Gem::Specification.Reset:
Invalid Active Developer Path on MAC Os X After Installing Ruby
Set Global Default Encoding For Ruby 1.9
How to Create a Sha1 Hash in Ruby
Rails Engines Extending Functionality
How to Match Something With Regex That Is Not Between Two Special Characters
Why Doesn't My Cron Job Work Properly
Gemfile.Lock Write Error, Permissions
How to Get Class Instances in Ruby
Pass a Variable into a Partial, Rails 3
How Does Load Differ from Require in Ruby
How to Get Rid of Non-Ascii Characters in Ruby
Rails 4.0 Strong Parameters Nested Attributes With a Key That Points to a Hash
How to Run All Tests With Minitest
Ruby on Rails - Unable to Convert "\X89" from Ascii-8Bit to Utf-8 for Xxx/Xxxx/Xxxx