Переменная присваивается в блоке в блоке

Сначала у меня был этот код, но он не работал:

VIM = Vimrunner::RSpec.configure do |config|
  config.reuse_server = true

  config.start_vim do
    vim = Vimrunner.start
    vim
  end
end

configure это просто метод, который делает настройки для сервера Vimrunner. start_vim Метод просто показывает, что должно быть выполнено для запуска vim, Однако это не имеет значения.

Что было на самом деле правильно, так это:

Vimrunner::RSpec.configure do |config|
  config.reuse_server = true

  config.start_vim do
    VIM = Vimrunner.start
    VIM
  end
end

Я не совсем понимаю это. В первом случае я фактически назначил Proc для VIM постоянный, как я узнал через irb тогда как во втором случае VIM константа была правильно назначена.

Таким образом, кажется, что я назначил константу VIM (которая находится в глобальном пространстве имен) с помощью этих блоков, и здесь мое понимание меня подводит:

Как я могу назначить переменную в блоке в блоке и позволить этому назначению вернуться в глобальное пространство имен?

Как это работает? Например, я попробовал этот код:

def foo
    yield
end

foo do
    a = 'Hello World!'
    a
end

puts a

Который покажет мне ошибку. Как сделать так, чтобы переменные внутри блоков ruby ​​помещались в область действия вызывающей стороны?

1 ответ

Решение

Вы можете использовать переменную экземпляра, если хотите получить к ней доступ снаружи? т.е. @a = 'Hello World!' а затем использовать puts @a, Локальные переменные привязаны к самому блоку, и поэтому не могут быть вызваны извне.

Я точно не знаю, каков ваш вариант использования, однако вы должны использовать это вместо

def foo
  yield
end

foo { 'Hello World!' }

или в вашем первом случае (так как это настройка конфигурации, я не уверен, имеет ли это значение, нужна ли вам переменная для ее хранения)

Vimrunner::RSpec.configure do |config|
  config.reuse_server = true
  config.start_vim { Vimrunner.start }
  config
end
Другие вопросы по тегам