Как я могу сделать локальную переменную в интерполяции строк недоступной извне? - PullRequest
0 голосов
/ 24 мая 2018

В этом коде:

s = "#{a = 2; b = 3; a * b}" # =>"6"
a # => "2"

локальные переменные a и b создаются в рамках интерполяции строки и могут быть доступны вне интерполяции строки, поскольку интерполяция строки не является блоком, несмотря нафигурные скобки.

Я хотел бы создать локальные переменные в рамках интерполяции строк, которые необходимы только там, а не в другом месте кода, и которые следует удалять после интерполяции строк, чтобы минимизировать побочные эффекты и потенциальные конфликты переменных.

Я пытался создать блок кода, чтобы добиться локальности переменных, но безуспешно:

s = "#{{a = 2; b = 3; a * b}}"

То же самое с do ... end.

s = "#{do a = 2; b = 3; a * b; end}"

Ответы [ 3 ]

0 голосов
/ 24 мая 2018

Также подход с новой функциональностью Ruby 2.5 yield_self

"#{ 2.yield_self{|a| 3.yield_self{|b| a*b}} }"
0 голосов
/ 24 мая 2018

вот моя попытка:

> s = "#{def yielder; yield; end; yielder do a=2; b=3; a*b; end;}"
#=> "6" 

> a
#=> NameError: undefined local variable or method `a' for main:Object
> b
#=> NameError: undefined local variable or method `b' for main:Object

Блоки обычно используют привязки, которые существуют, когда блок определен, за исключением случаев, когда существующая привязка конфликтует с переменной блока и переменной блока.Дополнительные локальные привязки могут быть определены в блоке, и они будут потеряны после завершения выполнения блока.

0 голосов
/ 24 мая 2018

Просто из любопытства.Следующий код не будет отбрасывать локальные переменные, но он эффективно сбрасывает их значения, поэтому вызов a (или b) после этого вернет nil:

%Q|#{
  a = 2
  b = 3
  (a * b).tap do 
    binding.local_variable_set(:a, nil)
    binding.local_variable_set(:b, nil)
  end
}|

Подходы ниже будут повышать NameError: undefined local variable or method 'a' ... вместо доступа к a после следующих утверждений:

"#{->() { a = 2; b = 3; a * b }.()}"

# or, credits to @engineersmnky
"#{->(a = 2, b = 3) { a * b }.()}"
"#{->(a, b) { a * b }.(2, 3)}"

Также:

"#{instance_eval { a = 2; b = 3; a * b }}"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...