一个非常奇怪的错误,显示一个对象为零。
主题中的代码是
while pbs:HasNext() do
local char = self.DecodeCharacter(pbs)
...
有人会认为,如果pbs:HasNext()
为true
,则表示pbs
nil
,无论如何。
然而,打印(pbs) - HTMLEntityCodec:DecodeCharacter
的第一行打印nil
function HTMLEntityCodec:DecodeCharacter(pbs)
print(pbs)
...
整个文件转储到下面,它被从1800多行剥离到110,因此SO用户可以清楚地了解他的上下文。但是剥离剥夺了代码中的所有逻辑,所以不要对此感到困惑。
#!/usr/bin/env lua
function Inherits( baseClass )
local new_class = {}
local class_mt = { __index = new_class }
function new_class:create()
local newinst = {}
setmetatable( newinst, class_mt )
return newinst
end
if baseClass then
setmetatable( new_class, { __index = baseClass } )
end
return new_class
end
-------------------------------------------
-- PushbackString
-------------------------------------------
PushbackString = Inherits({})
function PushbackString:Init(input)
self.input = input
self.pushback = nil
self.temp = nil
self.index = 0
self.mark = 0
end
-- Mark the current index, so the client can reset() to it if need be.
function PushbackString:HasNext()
return true
end
function PushbackString:Mark ()
self.temp = self.pushback
self.mark = self.index
end
BaseCodec = Inherits({})
function BaseCodec:Decode(input)
local buff = ''
local pbs = PushbackString:create()
pbs:Init(input)
while pbs:HasNext() do
local char = self.DecodeCharacter(pbs)
if char ~= nil then
buff = buff .. char
else
buff = buff .. pbs:Next()
end
end
return buff
end
HTMLEntityCodec = Inherits(BaseCodec)
-- HTMLEntityCodec.classname = ('HTMLEntityCodec')
function HTMLEntityCodec:DecodeCharacter(pbs)
print(pbs)
pbs:Mark()
end
DefaultEncoder = Inherits({})
function DefaultEncoder:Init(codecs)
self.html_codec = HTMLEntityCodec:create()
end
function DefaultEncoder:TestInput(input , strict)
print ("\n----------------8<----------------8<----------------\n")
print ("Input:\t" .. input)
-- default value
if strict == nil then strict = true end
-- nothing to do
if input == nil then return nil end
local working = input
local codecs_found = {}
local found_count = 0
local clean = false
while not clean do
clean = true
old = working
working = self.html_codec:Decode( working )
if old ~= working then
print ("Warning:\tINTRUSION DETECTED")
end
end
print ("Output:\t".. working)
return working
end
local default_encoder = DefaultEncoder:create()
default_encoder:Init()
default_encoder:TestInput("%25", true)
----------8<-----------8<--------------8<----------------
文件结束
控制台输出:
tzury@1005:~/devel/lua$ lua problem.lua
----------------8<----------------8<----------------
Input: %25
nil
lua: problem.lua:70: attempt to index local 'pbs' (a nil value)
stack traceback:
problem.lua:70: in function 'DecodeCharacter'
problem.lua:54: in function 'Decode'
problem.lua:96: in function 'TestInput'
problem.lua:109: in main chunk
[C]: ?
答案 0 :(得分:4)
在您的代码中,崩溃发生在这一行:
local char = self.DecodeCharacter(pbs)
问题是您使用不正确的参数数量调用DecodeCharacter
。
解决方案:像这样调用它(注意冒号):
local char = self:DecodeCharacter(pbs)
<强>解释强>:
当您使用冒号(:
)在Lua中定义函数时,您使用的语法糖隐藏了名为self
的隐式第一个参数。定义如:
function HTMLEntityCodec:DecodeCharacter(pbs) ... end
实际上是'翻译'到这个:
HTMLEntityCodec.DecodeCharacter = function (self, pbs) ... end
当您调用该函数时,您需要自己传递self
参数,或使用冒号调用自动提供它。在您的代码(self.DecodeCharacter(pbs)
)中,您传递的pbs
最终为self
HTMLEntityCodec.DecodeCharacter
,pbs
最终为nil
。以下两个电话都是等效的,应该可以解决问题:
local char = self.DecodeCharacter(self, pbs)
local char = self:DecodeCharacter(pbs)