What's the Difference Between "=" & "=>" and "@Variable", "@@Variable" and ":Variable" in Ruby

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.

Ruby - Difference between :variable and @variable

Is my understanding of the difference between :my_selections and
@my_selections correct?

Nope :(

: indicates a symbol, its not an alias for anything intrinsically. It's like an immutable string, which is often used as a name to represent something.

In places where the Rails api accepts a symbol in place of an instance variable, internally it's actually doing this:

self.instance_variable_get "@#{my_symbol}"

Which actually returns the value of the requested instance variable.

So the only reason that you think symbol correspond to instance variable at all, is because the code that drives the API you are using works that way. Without a framework to do that for you, there is no correlation at all.

Why would switching to :my_selection resolve my original error?

for_form(model_instance) will generate a form that submits to the create action if the model instance is unsaved, or to the update action if the model is already exiting in your DB.

No I don't know what's in @my_selection, but whatever class it is doesn't seem to be generating the routes properly.

resources :my_selections

Will generate a route you would invoke like this:

my_selections_path

How your form is generating a route for my_selection_index_path I'm not sure and it really depends on what your models are.

And when you pass a symbol instead, and there is no corresponding ivar, it uses that as the model name for route generation. Which would do the right thing by trying to invoke my_selections_path, which is directly based on the symbol you pass in.

What's the difference between #@{var} and @#{var} in Ruby?

It's the #{(expression)} that's significant.

If the expression is #{name} then that's substituting the variable name which in all your examples comes from the parameters input into the method.

If the expression is #{@name} then that's substituting the variable @name which is defined in the fourth line of your methods.

@#{name} is not a special construct. It's just the string @ followed by the contents of the variable name.

The reason it didn't work in your second example is that you simply haven't defined a variable vendor.

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.

How can Ruby tell the difference between variables and method names if they have the same scope?

variable would be first, but you can call method:

def foo
33
end

foo = 44

>foo
#=> 44
>foo() #also you can call it by: self.foo || My omission, thanks @CarySwoveland

#=> 33

On question

why?

@SergioTulentsev gave a good answer:

local variable has priority over bracketless method call because otherwise it wouldn't be possible to refer to the variable

Also, for more information about methods and variables you can read here

Difference between various variables scopes in ruby

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

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

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

  4. That's just how Ruby is.

  5. One has already been given by Chris.

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

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

What is the difference between using local variable or instance variable in an Rails API?

The performance difference will be negligible.

But there's two competing guidelines at work. One is "Always use the weakest construction." Don't use double "quotes" if you can use single 'quotes'. Don't use a regular expression if you can use String#index. Don't use an instance variable if you can use a local variable.

The other guideline is "Design for testing." If you use an instance variable, your test can inspect it with assigns(:user). That rule trumps the "weakest construction" rule. So use an instance variable, and write lots of automated tests!



Related Topics



Leave a reply



Submit