@ Variables in Ruby on Rails

@ 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.

Explanation of the @ variables inside Rails models

To add to the current answers, @instance_variables are from object orientated programming...

In object-oriented programming with classes, an instance variable is a variable defined in a class (i.e. a member variable), for which each instantiated object of the class has a separate copy, or instance.



OOP

"Normal" programming has variables as pieces of data -- strings, integers etc. These are independent & can only interact as part of other functions, depending on their scope.

Object Orientated programming (OOP) can treat variables as pieces of editable data (known as classes). These classes can be invoked, edited and most importantly interacted...

#app/models/product.rb
class Product < ActiveRecord::Base
#-> class
end

def new
@product = Product.new #-> creating a new instance of the class
end

Ruby/Rails is object orientated; it works by giving you a series of objects to load & interact with. The most notable example is with game programming:

Sample Image

The way object orientation works is to invoke/initialize an instance of a class (in our case Product), allowing you to manipulate it.

Class instances hold the object in memory, allowing you to perform actions on the class itself. To do this, you'd store the instance of the class in a variable, allowing you to interact with the variable itself:

@product = Product.new
@product.save

--

Instance variables are only valid within the context of the class:

# app/controllers/products_controller.rb
class ProductsController < ApplicationController
def show
@product = Product.new #-> @product only available within ProductsController
end
end

The controllers in Rails are classes, invoked through a rack request:

Request > Rack > Routes > ProductsController.new(request).show > Response

If you want your @instance_variable available in all methods of the class, it has to be at instance level...

# app/controllers/products_controller.rb
class ProductsController < ApplicationController
def show
@product = Product.new
product_save
end

private

def product_save
@product.save #-> @product available in instance of ProductsController class
end
end

The most common use for @instance_variables are to store / manipulate instance-centric data. A good example (for our Product example) could be the stock level:

#app/models/product.rb
class Product < ActiveRecord::Base
def stock
@qty / @orders
end
end

Because you can use getter/setter methods within Ruby, you can define the instance values of a class, accessing them through other instance data:

@product = Product.find x
@product.stock #-> outputs stock value for that product

Understanding Rails Instance Variables

Instance variables are in the instance class scope. In Ruby on Rails, because the way how that API was built, instance variables are also available in the views.

You need to be aware of that new and create methods are commonly used in different ProductsController instances.

First request: GET http://localhost:3000/product/new

When you ask for the new action (I suppose that is a form), Rails API implementation at a given point creates an instance of ProductsController and sends the new message to that instance (calls the new method). Then, the instance variable @product is created and available in any method, or in any view that the action renders. At a given point, Rails replies with a web page and the class instance, and all its instance variables, are destroyed (won't be available anymore).

Second request: POST http://localhost:3000/product/create

When you submit the form for database persistence, again a new controller instance is created, and the create method is called. Because is a new instance, the @product doesn't have any value.

Note, however, that there is a difference between rendering a view (like its happening in the new action) and a redirect (like you do in the create action if @product.save is true). When you render, you remain in the same controller instance, with you redirect, new server request happens, so the previous controller instance is destroyed and a new controller instance is created.

The before action

before_action is called before you actually start executing the action code. In Rails perspective, an action is not a Ruby method. The class method is the definition of that action:

From Rails guides:

A controller is a Ruby class which inherits from ApplicationController
and has methods just like any other class. When your application
receives a request, the routing will determine which controller and
action to run, then Rails creates an instance of that controller and
runs the method with the same name as the action.

The action acts as an entry point determined by the routes. If you call create inside new, it won't trigger that before_action again.

Are @@variables in a Ruby on Rails controller specific to the users session, or are all users going to see the same value?

@@ComputedData is a class variable. All users are going to see the same data, so baaaad idea.

Defining instance variables in rails controllers

In this case, defining instance variable in users#new, for example, is necessary for it to be accessible in view. Rails uses this specific mechanism to copy all the instance variables defined in controller context to view.

On the other hand, in sessions#create you only want to redirect the user if sign in is successful and display sign in form otherwise, which - as you see in sessions#new - doesn't require any instance variables defined. So local variable in this case is sufficient.

Lifecycle of Instance variables in Ruby on Rails

Rails controller is instantiated per request. It means that every time you receive a request all instance variables are nil and you need to initialize them.

Accessing instance variable in rails and ruby

Use attr_reader to read the value of an instance variable

class Person
attr_reader :name

def initialize(name)
@name = name
end
end

john = Person.new("John")
john.name #=> "John"

attr_reader adds a getter method to the class, in this case

def name
@name
end

Hope that helps!

ruby on rails, colon at back or front of variables

What i have understand so far is that :variable in ruby, is to say that this variable will not be able to change, which is similar to constant in other language.

I'm not sure if I understand that statement. In Ruby, constants start with an uppercase letter:

Foo = 1

Reassignment generates a warning:

Foo = 1
Foo = 2 #=> warning: already initialized constant Foo

Variables start with a lowercase letter and reassignment doesn't cause a warning (they are supposed to change):

foo = 1
foo = 2 # no warning

Symbols start with a colon:

:a_symbol
:Uppercase_symbol
:"i'm a symbol, too"

They often represent static values, e.g. :get and :post. Symbols are memory efficient, because they are created only once - the same symbol literal always returns the same object. Checking if two symbols are equal is a cheap operation.

Both key: and method: (...) What does that this represent?

This is an alternate syntax for hashes. You can type it in IRB to see the result:

{ foo: 1, bar: 2 }
#=> {:foo=>1, :bar=>2}

There are double colons inbetween variables? now I am guessing that Blog: is one variable, and :Application is constant.

No, Blog and Application are both constants and :: is the scope resolution operator. It can be used to access nested constants, e.g.:

module Foo
class Bar
BAZ = 123
end
end

Foo::Bar::BAZ #=> 123

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)



Related Topics



Leave a reply



Submit