What is the difference between @@ and @ in Ruby?
A variable prefixed with @@
is a class variable and one prefixed with @
is an instance variable. A great description can be found in this answer: https://stackoverflow.com/a/5890199/1181886
Difference between .. and ... in Ruby
In ruby 1...5
gives you a range which doesn't include 5
whereas 1..5
gives you a range which does include 5
eg:
>> (1..5).to_a
[
[0] 1,
[1] 2,
[2] 3,
[3] 4,
[4] 5
]
>> (1...5).to_a
[
[0] 1,
[1] 2,
[2] 3,
[3] 4
]
What is the difference between @@ and @ and when should I use one rather than another?
@
is an instance variable. It is a variable attached to a particular object. These are how you store data on an object.
class Thing
# These two methods are basically what `attr_accessor :stuff` does.
def stuff=(value)
@stuff = value
end
def stuff
@stuff
end
end
f1 = Foo.new
f1.stuff = 42 # f1's @stuff is set to 42
f2 = Foo.new
f2.stuff = 23 # f2's @stuff is set to 23
p f1.stuff # 42
p f2.stuff # 23
@@
is a class variable. They are to be avoided because of a quirk: they're shared with all subclasses.class Vehicle
@@type = 'vehicle'
def self.type
@@type
end
end
class Car < Vehicle
# This is the same @@type as in Vehicle
@@type = 'car'
end
class Plane < Vehicle
# This is the same @@type as in Vehicle
@@type = 'plane'
end
p Vehicle.type # plane
p Car.type # plane
p Plane.type # plane
Instead, use "class instance variables". Everything in Ruby is an object including classes. They are instances of Class
. class Vehicle ... end
is syntax sugar for Vehicle = Class.new do ... end
. And like any object, they can have instance variables.# Same as `class Vehicle` just to demonstrate.
Vehicle = Class.new do
# This is an instance variable on the Vehicle Class object.
# Not Vehicle.new, but just Vehicle.
@type = 'vehicle'
def self.type
@type
end
end
# class Plane < Vehicle
Plane = Class.new(Vehicle) do
# This is an instance variable on the Plane Class object.
@type = 'plane'
end
# And the sugary way.
class Car < Vehicle
# This is an instance variable on the Car Class object.
@type = 'car'
end
p Vehicle.type # vehicle
p Car.type # car
p Plane.type # plane
See Class Instance Variables in Ruby and The Official Ruby FAQ for more. what is the difference between += and =+ in ruby?
There's no such token as =+
; it's actually two tokens: assignment followed by the unary +
operator; the latter is essentially a no-op, so @@num_things =+ 1
is equivalent to @@num_things = 1
.
Since there is a +=
token, the language parser will parse it as a single token.
(In the early formulations of BCPL which was the precursor to C, the modern -=
operator was written as =-
.)
What's the difference between = & = and @variable, @@variable and :variable in ruby?
OK.
The difference between the =
and the =>
operators is that the first is assignment, the second represents an association in a hash (associative array). So { :key => 'val' }
is saying "create an associative array, with :key
being the key, and 'val'
being the value". If you want to sound like a Rubyist, we call this the "hashrocket". (Believe it or not, this isn't the most strange operator in Ruby; we also have the <=>
, or "spaceship operator".)
You may be confused because there is a bit of a shortcut you can use in methods, if the last parameter is a hash, you can omit the squiggly brackets ({}
). so calling render :partial => 'foo'
is basically calling the render method, passing in a hash with a single key/value pair. Because of this, you often see a hash as the last parameter to sort of have a poor man's optional parameters (you see something similar done in JavaScript too).
In Ruby, any normal word is a local variable. So foo
inside a method is a variable scoped to the method level. Prefixing a variable with @
means scope the variable to the instance. So @foo
in a method is an instance level.
@@
means a class variable, meaning that @@
variables are in scope of the class, and all instances.
:
means symbol. A symbol in Ruby is a special kind of string that implies that it will be used as a key. If you are coming from C#/Java, they are similar in use to the key part of an enum. There are some other differences too, but basically any time you are going to treat a string as any sort of key, you use a symbol instead.
what's difference between @ and @@ in a module?
Class variables can be shared between modules and classes where these modules are included.
module A
@@a = 5
end
class B
include A
puts @@a # => 5
end
Meanwhile, instance variables belong to self
. When you include module A
into class B
, self
object of A
is not the same as self
object of B, therefore you will not be able to share instance variables between them.module A
@a = 5
end
class B
include A
puts @a # => nil
end
Difference between the @ instance variable belonging to the class object and @@ class variable in Ruby?
@one
is an instance variable of the class MyClass
and @@value
is the class variable MyClass
. As @one
is an instance variable it is only owned by the class MyClass
(In Ruby class is also object), not shareable, but @@value
is a shared variable.
shared variable
class A
@@var = 12
end
class B < A
def self.meth
@@var
end
end
B.meth # => 12
non shared variableclass A
@var = 12
end
class B < A
def self.meth
@var
end
end
B.meth # => nil
@two
is an instance variable of the instances of the class MyClass
.Instance variables are private property of objects, thus they wouldn’t share it. In Ruby classes are also objects. @one
you defined inside a class MyClass
, thus it is only owned by that class defining it. On the other hand @two
instance variable will be created when you will be creating a object of the class MyClass
, say ob
, using MyClass.new
. @two
is only owned by ob
, none other objects have any idea about it.
What does @@variable mean in Ruby?
A variable prefixed with @
is an instance variable, while one prefixed with @@
is a class variable. Check out the following example; its output is in the comments at the end of the puts
lines:
class Test
@@shared = 1
def value
@@shared
end
def value=(value)
@@shared = value
end
end
class AnotherTest < Test; end
t = Test.new
puts "t.value is #{t.value}" # 1
t.value = 2
puts "t.value is #{t.value}" # 2
x = Test.new
puts "x.value is #{x.value}" # 2
a = AnotherTest.new
puts "a.value is #{a.value}" # 2
a.value = 3
puts "a.value is #{a.value}" # 3
puts "t.value is #{t.value}" # 3
puts "x.value is #{x.value}" # 3
You can see that @@shared
is shared between the classes; setting the value in an instance of one changes the value for all other instances of that class and even child classes, where a variable named @shared
, with one @
, would not be.[Update]
As Phrogz mentions in the comments, it's a common idiom in Ruby to track class-level data with an instance variable on the class itself. This can be a tricky subject to wrap your mind around, and there is plenty of additional reading on the subject, but think about it as modifying the Class
class, but only the instance of the Class
class you're working with. An example:
class Polygon
class << self
attr_accessor :sides
end
end
class Triangle < Polygon
@sides = 3
end
class Rectangle < Polygon
@sides = 4
end
class Square < Rectangle
end
class Hexagon < Polygon
@sides = 6
end
puts "Triangle.sides: #{Triangle.sides.inspect}" # 3
puts "Rectangle.sides: #{Rectangle.sides.inspect}" # 4
puts "Square.sides: #{Square.sides.inspect}" # nil
puts "Hexagon.sides: #{Hexagon.sides.inspect}" # 6
I included the Square
example (which outputs nil
) to demonstrate that this may not behave 100% as you expect; the article I linked above has plenty of additional information on the subject.Also keep in mind that, as with most data, you should be extremely careful with class variables in a multithreaded environment, as per dmarkow's comment.
Difference between and and && in Ruby?
and
is the same as &&
but with lower precedence. They both use short-circuit evaluation.
WARNING: and
even has lower precedence than =
so you'll usually want to avoid and
. An example when and
should be used can be found in the Rails Guide under "Avoiding Double Render Errors".
Difference between various variables scopes in ruby
Class variables are the same for all instances, because they're class variables–associated with the class. Everything access the same variable, including each instance.
No. Local variables are just that–local. They may be local to a function, or local to the class declaration, which is different than being a class variable. Locals in a class declaration go out of scope when the class declaration ends.
That's because they're exactly the same–they're global. Global state is always evil; this is not a property of the language or environment. That said, some global state may be required–that's just the way it is. It makes sense to use global state when there's global state. The trick is to use global state properly, which is sometimes a non-trivial endeavor.
That's just how Ruby is.
One has already been given by Chris.
I would think this question would be largely self-answering. Global when the entire world needs access. Instance when it's specific to a class instance. Local when it's only required in a local scope (e.g., a method, a block (note differences between 1.8 and 1.9 with regard to block scope), etc.) Constant when the variable isn't supposed to change. A class variable when it's something that either every instance needs, or if exposed via a class method, something tightly associated with a class.
There is no "most use-cases", it totally depends on what you're doing with the variable. And
public
isn't the de facto choice in Java–it depends on the entity in question. Default Java scope is package-private (methods, properties). Which to use in Ruby depends entirely upon the use-case, noting that as with Java, and even more easily in Ruby, things can be circumvented.
Related Topics
How to Tell a Ruby Method to Expect a Specific Parameter Type
How to Directly Install a Gem from a Git Repository
How to Evaluate a Block Inside a Proc
How to Handle Serialized Edit Fields in an Active Admin Resource
How to Show Longer Traces in Rails Testcases
Nlp to Classify/Label The Content of a Sentence (Ruby Binding Necesarry)
Good Forms Helpers for Sinatra
Understanding The Behaviour of Inject Used with a Lambda in Ruby
Error Generating Source Map - Grunt and SASS Configuration
How to Open File in Default Application. Ruby
Indent Multiline String in Erb
Where Are Keywords Defined in Ruby
Phusion Passenger with Ruby 1.8 and 1.9
One or More Params in Model Find Conditions with Ruby on Rails
Ruby - Generate All Two Letter Words
Current Password Can't Be Blank When Updating Devise Account