В чем разница между использованием локальной переменной или переменной экземпляра в Rails API? - PullRequest
0 голосов
/ 07 июня 2018

В обычном приложении мы используем переменные экземпляра, чтобы мы могли обращаться к ним в наших представлениях.Но в приложении Rails API, что бы это было нужно?

Есть ли разница в производительности между использованием локальной переменной или переменной экземпляра В этом контексте контроллеров?

Я не понимаю, почему rails использует экземплярпеременные в методе create и index в приложении API, сгенерированном scaffold, если переменная не используется повторно

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

Ответы [ 4 ]

0 голосов
/ 07 июня 2018

Существует очень четкое практическое различие в том, как работают лексические переменные и переменные экземпляра:

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

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

Поскольку переменные экземпляра присоединены к экземпляру, они могут совместно использоваться методами объекта без передачи по значению, как обычноиспользуется обратными вызовами:

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

Это может быть очень полезно при рассмотрении соглашения о конфигурации фокуса рельсов.Контроллеры IVAR также доступны в представлении через контекст представления.

Лексические переменные, с другой стороны, существуют только в лексической области, где определены (метод, блок, процесс или лямбда):

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>

Они предпочтительнее, когда вам нужен короткийживая переменная с локальной областью видимости.В Rails также есть locals, который на самом деле является хешем, в который можно добавлять вещи при рендеринге, что не должно быть связано с концепцией лексических переменных в Ruby.Rails использует method_missing в контексте представления для передачи хешу локальных данных.

Разница в производительности, скорее всего, крайне незначительна, поскольку обе являются просто переменными, которые связаны с областью действия - либо объектом, либо методом / блоком,Лексическая переменная будет переработана GC, когда область будет закрыта (метод завершится), хотя переменная экземпляра будет сохранена с объектом.Это редко проблема, хотя.

0 голосов
/ 07 июня 2018

Разница в производительности будет незначительной.

Но есть два конкурирующих руководства в работе.Один из них «Всегда используйте самую слабую конструкцию».Не используйте двойные «кавычки», если вы можете использовать одинарные «кавычки».Не используйте регулярные выражения, если вы можете использовать String # index.Не используйте переменную экземпляра, если вы можете использовать локальную переменную.

Другое руководство - «Дизайн для тестирования».Если вы используете переменную экземпляра, ваш тест может проверить ее с помощью assigns(:user).Это правило превосходит правило "самой слабой конструкции".Так что используйте переменную экземпляра и напишите множество автоматических тестов!

0 голосов
/ 07 июня 2018

Нет разницы, говоря о функциональности в этом примере.но создание переменной экземпляра означает, что эта переменная будет доступна позже, возможно, в представлении или в другом методе, в этом случае речь идет об API (у вас нет представлений), если вы не планируете использовать @user в другомнапример, метод внутри этого контроллера, вам не нужно его создавать, достаточно только локальной переменной.

Говоря о производительности, я не думаю, что будет много различий, по крайней мере, что-то заметное,

И в качестве комментария:

"Переменная экземпляра продолжает существовать в течение всего срока службы объекта, который его содержит. Локальная переменная существует только в пределах одного метода, блока или тела модуля."

0 голосов
/ 07 июня 2018

В этом точном примере функциональной разницы нет.

Есть ли какая-либо разница в производительности?Или есть материал разница в производительности?Я не знаю ответа на первый вопрос.Мне кажется, ответ на второй вопрос - «нет», если вы не делаете это в невообразимо широком масштабе.Даже тогда трудно представить.

Кстати, вы могли бы просто сделать:

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

В вашем примере нет необходимости в переменной, user или @user.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...