Замыкание лямбды или про c собирается при создании лямбды. Таким образом, тело лямбда имеет доступ ко всем локальным переменным, которые были определены и видимы в точке, где была создана лямбда. Это не включает другие переменные, определенные только при вызове лямбда.
Таким образом, вы должны передать в него любые данные, которые необходимы лямбда (и которые еще не были доступны в замыкании, когда лямбда была создана) с помощью параметр.
Наконец, чтобы иметь возможность вызывать лямбду, вам необходимо сделать ее доступной в той области, в которой вы хотите ее использовать. Это может выглядеть так:
class MyController < ApplicationController
# define a local variable which will be available in the lambda's closure
scope = ENV['scope']
# Assign the lambda to a constant. That way, it can be resolved
# by every method in the current class
FIRST = lambda do |data|
# The scope variable is available here when the lambda is called
# since it is available in the closure from the lambda's creation.
#
# Since the data variable is not available during the lamda's
# creation, we need to get it from a parameter from the caller.
User.where(scope: scope).first.name + data
end
def getuser
data = params[:data]
FIRST.call(data)
end
end
С учетом сказанного, более распространенный подход к этому - использование полных методов для объекта вместо передачи лямбда-выражений вокруг:
class MyController < ApplicationController
def getuser
data = params[:data]
first(data)
end
private
def first(data)
User.first.name + data
end
end
Это позволяет избежать необходимость рассуждать о содержимом (в основном неявного и не очень видимого) закрытия в пользу простого вызова метода, который имеет доступ к переменным экземпляра и методам текущего объекта.
Javascript (где анонимные функции обычно передаются с закрытием, немного похожим на лямбда-выражения Ruby), вы должны попытаться адаптироваться к Ruby -проходу и избегать такой конструкции в пользу объектов с явными методами .