Однако мне это удалось, когда я использовал стандартную библиотеку ERB следующим образом:
proc = Proc.new do
@text = "Hello, World"
@num = 100
end
ERB.new('<%= @text %> | <%= @num %>').result proc.binding # => "Hello, World | 100"
Если я вставлю строку require 'erb'
в начало вашего кода и добавлю 'p' к вашей последней строке, я получу следующий вывод:
" | "
Я проверил это на рубинах: 1.8.7, 1.9.3, 2.0, 2.1.
Причина, по которой @text и @num равны нулю, заключается в том, что они не являются частью привязки proc. Во-первых, код в блоке, как и код в def, даже не выполняется до тех пор, пока блок не будет вызван, поэтому не имеет значения, является ли процедура пустой или имеет в ней переменные @, если процедура никогда не выполняется.
Во-вторых, единственные привязки (т. е. переменные и их значения в окружающей области видимости), которые могут быть видны вашей процедуре, — это self=main. И переменная @ присоединяется к любому объекту, который является self, когда переменная @ появляется. В результате, когда ваш proc все-таки выполнится, переменные @ улетят и прикрепятся к main, что означает, что они вообще не будут иметь никакой связи с вашим proc.
В-третьих, вы даже не можете изменить значение для себя в привязке:
class Dog
def bark(proc_obj)
#self is a dog instance in here
proc_obj.call
p @text
end
end
my_proc = Proc.new{@text = "hello"}
Dog.new.bark my_proc
puts @text
--output:--
nil
hello
Когда процедура выполняется, в окружающей области видимости есть переменная с именем self, и ее значением является экземпляр собаки, однако переменная @ в процедуре присоединяется к self=main (последний оператор puts показывает это), а не к self=dog_instance . Для меня это указывает на то, что self действует как локальная переменная, и процесс закрывается по локальной переменной с именем self в области верхнего уровня. Затем в def ruby создает еще одну локальную переменную с именем self, которую ruby устанавливает равной экземпляру собаки, вызвавшему def. В результате self верхнего уровня и self в def являются двумя разными переменными, и поэтому значение self в def не влияет на значение, которое proc видит для себя.
Наконец, если вы посмотрите документацию для ruby 2.1, класс Binding теперь имеет метод для извлечения переменных из привязки, и он называется local_variable_get()
. Обратите внимание на имя local. Не существует метода с именем instance_variable_get()
, потому что, насколько я могу судить, переменные экземпляра не являются частью привязки — вместо этого они улетают и прикрепляются к какому-то объекту, т. е. тому, чему я был равен во время создания процедуры — не чему равен self при выполнении proc.
person
7stud
schedule
27.05.2014
TypeError: can't define singleton
- person August   schedule 26.05.2014