简体   繁体   中英

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

In a common application we use instance variables so that we can access them in our views. But in a Rails api application what would the need be?

Is there any performance difference between using a local or instance variable In this context of Controllers?

I do not understand why rails uses instance variables in the create and index method in an api application generated by scaffold if the variable is not reused

def show
    user = User.find(params[:id])
    render json: UserSerializer.new(user)
 end


def show
    @user = User.find(params[:id])
    render json: UserSerializer.new(@user)
end

In this exact example, there is no functional difference.

Is there any performance difference? Or is there material performance difference? I do not know the answer to the first question. The answer to the second question, I imagine, is 'no' unless you are doing this at some unimaginably large scale. Even then, it's hard to imagine.

BTW, you could just do:

def show
  render json: UserSerializer.new(User.find(params[:id]))
end

In your example, there is no need for a variable, either user or @user .

There is a very clear practical difference in how lexical and instance variables work:

class Thing
  def initialize
    @ivar = "Hello World"
  end
  def foo
    @ivar
  end
end

> Thing.new.foo
=> "Hello World"

Since instance variables are attached to the instance they can be shared among methods of an object without passing by value as typically used by callbacks:

class API::V1::ThingsController < ::ApiController
  before_action :set_thing, except: [:create, :index]

  def show
    respond_with @thing
  end

  # ...

  private

    def set_thing
      @thing = Thing.find(params[:id])
    end
end

This can be immensely useful when considering the convention over configuration focus of rails. Controller IVARs are also available in the view through the view context.

Lexical variables on the other hand only exist in the lexical scope where the are defined (the method, block, proc or lambda):

class Thing
  def initialize
    lex = "Hello World"
  end
  def foo
    lex
  end
end

> Thing.new.foo
NameError: undefined local variable or method `lex' for #<Thing:0x007f87068b5968>

They are preferable when you need a short lived variable with a local scope. Rails also has locals which is actually a hash where you can stuff things when rendering which should not be conflated with the Ruby concept of lexical variables. Rails uses method_missing in the view context to proxy to the locals hash.

The performance difference is most likely extremely negible as both are just variables that are bound to a scope - either the object or a method/block. The lexical variable will recycled by the GC when the scope is closed (the method finishes) though while an instance variable will persist with the object. This is rarely an issue though.

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!

there is no difference talking about functionality in that example. but creating an instance variable is to let that variable be accesible later, maybe on the view or in another method, in this case, talking about api's (you don't have views), if you do not plan to use @user in another method inside that controller for example, you don't need to create it, with just a local variable, it's enough.

talking about performance, I don't think there will be much differences, at least something noticeable.

And as a comment:

"An instance variable continues to exist for the life of the object that holds it. A local variable exists only within a single method, block or module body."

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM