Ruby имеет область действия сценария, область определения модуля/класса/метода и область блока. Только блоки создают вложенные области. Итак, вам нужно использовать блок для определения вашего метода. К счастью, есть способ для определения методов, которые принимают блок:
def f
v = 5
define_method :g do
v
end
g
end
f
# => 5
Однако, обратите внимание, что это делает не делать то, что вы думаете, что делает (и ни один не делает исходный код). Он не определяет способ g
, вложенный в метод f
. Ruby не имеет вложенных методов. Методы всегда принадлежат модулям (классы - это модули), они не могут принадлежать методам.
Это способ определения метода f
, который при запуске определяет метод g
, а затем вызывает этот метод.
Наблюдайте:
methods.include?(:g)
# => true
вы определили новый метод верхнего уровня (на самом деле частный метод экземпляра Object
) под названием g
, и вы будете определять его снова и снова и снова, каждый раз f
получает называется.
То, что вы, вероятно, хотите, лямбда:
def f
v = 5
g = -> { v }
g.()
end
f
# => 5
В комментариях к другой ответ Вы писали:
Ладно, так что я возиться с лямбды, и я заметил, что все Я делаю до v
внутри g
не отражается в v
раз g
возвращается. Могу ли я внести изменения в палку v
?
def f
v = 5
g = -> { v = 'Hello' }
g.()
v
end
f
# => 'Hello'
Как вы можете видеть, изменение v
делает "кнут" после g
возвращается.
Рубин не имеет функции. Он имеет методы и имеет блоки. Методы имеют новые области применения, блоки имеют вложенные области. –
@ JörgWMittag На самом деле, как я узнал из ответа Фреда, Ruby имеет методы и ** замыкания **. Блоки - это всего лишь один из трех видов замыканий в Ruby. Есть также Лямбдас и Прок. – anthropomorphic
Lambdas и Procs - это просто объекты, которые создаются путем передачи блоков методам. (Или с использованием синтаксиса лямбда-литерала.) –