在下面的代码中,为什么data
变量作为类变量而不是实例变量正常工作? (注意:我试图简化/重现脚本的必要位以使问题有意义。如果需要更多,我可以发布完整的脚本。)
require 'prawn'
class Test
include Prawn
def initialize (data, filename) #data is an array of arrays
@@data = data #this is the variable in question, when @data the script fails
@filename = filename
end
def to_pdf
Document.generate("#{@filename}.pdf") do #included from Prawn
@@data.each do |item|
do some stuff to the data
end
make_table with the data that's been worked on
end
end
end
test_run = Test.new([[1, 2, 1], [1, 2, 2]], "testfile.pdf")
test.to_pdf
如果@@data
改为@data
,则脚本会返回undefined method 'each' for nil:NilClass (NoMethodError)
为什么会这样?包含的模块不应该同样可以访问实例变量吗? (为什么@filename变量是一个实例方法呢?)
答案 0 :(得分:4)
来自fine manual:
使用隐式块表单时,Prawn将在
Prawn::Document
的实例中评估块,从而简化语法。但请注意,您将无法在此块中引用封闭范围内的变量。Prawn::Document.generate "example.pdf" do # ...
如果需要访问本地变量和实例变量,请使用下面显示的显式块表单。在这种情况下,Prawn产生一个
PDF::Document
的实例,该块是一个普通的闭包:Prawn::Document.generate "example.pdf" do |pdf| #...
to_pdf
中的块正在Prawn::Document
实例的内容中进行评估,而不是在对象的上下文中,这意味着没有@data
实例变量,所以{{当您尝试访问它时,会创建值为@data
的1}}。您可能希望使用具有单个参数的块:
nil