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.
@ variables in Ruby on Rails
title
is a local variable. They only exists within its scope (current block)
@title
is an instance variable - and is available to all methods within the class.
You can read more here:
http://strugglingwithruby.blogspot.dk/2010/03/variables.html
In Ruby on Rails - declaring your variables in your controller as instance variables (@title
) makes them available to your view.
What does a normal variable defined inside a Ruby class mean?
It is a local variable. See the official documentation about "Local variables".
Local variables, when declared within the scope of a Class, get evaluated whenever the class is loaded. Try to run this:
class MyClass
bad_idea = 1/0
def initialize
puts "this is silly #{bad_idea}"
end
end
puts "I told you this wouldn't work!"
You'll get a ZeroDivisionError: divided by 0
and "I told you this wouldn't work!"
will never get printed.
Understanding Ruby variables and symbols?
Variables starting with @
are instance variables, "properties" in other languages. Whereas 'classic' variables are local to the scope of their method/block, instance variables are local to a specific instance
of an object, for example:
class Foo
def initialize(bar)
@bar = bar
end
def bar
@bar # the variable is specific to this instance
end
def buzz
buzz = 'buzz' # this variable is not accessible outside of this method
end
end
You may also see variables starting with @@
, which are class variables, and are accessible by every instance of the class and shared with every instance of the subclass. Usage of those variables is usually discouraged, primarily because subclasses share the variable, which can cause a lot of mess.
In Ruby everything is an object, classes are objects (instances of class Class
), so you can also have class instance variables:
class Foo
def self.bar
@bar #we are in class Foo's scope, which is an instance of class Class
end
def self.bar=(bar)
@bar = bar
end
def bar
@bar # Foo.new.bar != Foo.bar
end
end
What you call "variables with a colon" are not variables. They are a particular type of string, called a symbol, that is immutable and optimized for quick identification by the interpreter, in fact, those are stored internally as pointers, so that :this == :this
is a very quick operation.
This property makes them good candidates for hash keys because they offer quick retrieval or for "flags" to pass to a method; Think of them as a sort of loose constant that "stands for" what they say. Their immutability is also dangerous: All symbols ever created never get garbage collected; It's easy to create a memory-leak by creating thousands of symbols, so use them wisely.
UPDATE since ruby 2.2 symbols may be garbage-collected in certain cases (when no reference is kept and no comparison is needed)
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 does the : mean in rails before a variable name?
It's a symbol, which is a Ruby language construct.
Symbols are similar to strings, but this blog post explains the details.
@
means an instance variable on the class: it's basically a variable that's shared among all methods on an instance of a class. It has no relation to :
.
What does the $ character mean in Ruby?
$: is the global variable used for looking up external files.
From http://www.zenspider.com/Languages/Ruby/QuickRef.html#18
$: Load path for scripts and binary modules by load or require.
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
Related Topics
How to Make --No-Ri --No-Rdoc the Default For Gem Install
How to Assign a Variable in an If Else Statment Check
How to Remove Rvm (Ruby Version Manager) from My System
How to Avoid Nomethoderror For Missing Elements in Nested Hashes, Without Repeated Nil Checks
How to Get the Current Absolute Url in Ruby on Rails
Difference Between "Or" and || in Ruby
How to Generate a Random String in Ruby
Ruby Array Access 2 Consecutive(Chained) Elements At a Time
Error: While Executing Gem ... (Gem::Filepermissionerror)
Difference Between Require_Relative and Require in Ruby
How to Pick Randomly from an Array
Look Up All Descendants of a Class in Ruby
Check If a String Contains Only Digits in Ruby
Why Is Division in Ruby Returning an Integer Instead of Decimal Value
Bundle Install Fails With Ssl Certificate Verification Error