为什么类变量有效但实例变量在类[Ruby]中包含模块时返回nil?

时间:2011-12-06 02:01:24

标签: ruby class variables module prawn

在下面的代码中,为什么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变量是一个实例方法呢?)

1 个答案:

答案 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