我有以下代码:
class MyXmlReader
attr_accessor :filename, :lines
def initialize(filename)
@filename = filename
@line_hash = {}
end
def read
reader = Nokogiri::XML::Reader(open(@filename))
Xml::Parser.new(reader) do
... do stuff
@line_hash[var] = line # ERROR!
end
end
end
看起来该块在新范围内运行。因为我得到了:
NoMethodError: undefined method `[]' for nil:NilClass
通过创建局部变量然后将这些变量分配给read
方法末尾的实例变量,可以轻松解决这个问题。但我想知道为什么在块中可以访问局部变量,而不是实例变量。
答案 0 :(得分:3)
这是因为局部变量与实例变量不同,具有词法范围。 This Wikipedia article可能有帮助。
答案 1 :(得分:2)
有趣的问题不是为什么局部变量可以在块中访问(当然,块是闭包,从周围范围访问局部变量是有点重要的),而是为什么实例变量不是。实际上,因为它应该可以访问。
但是,如果该块被instance_eval
编辑或instance_exec
,则self
的值将更改为{instance_eval
的接收方1}}或instance_exec
消息,实例变量总是在self
中查找,因此self
现在是一个不同的对象,它可能不会有{{1}实例变量。您必须查看@line_hash
的实现才能找到答案。
答案 2 :(得分:0)
我无法重现这个问题。这是一个简单的测试用例,我创建了:
class MyReader
def initialize
@line_hash = {}
end
def read
[1,2].each do |x|
@line_hash[x] = '0'
end
end
end
p MyReader.new.read