#lua
#lua
Вопрос:
Очень странная ошибка, показывающая, что объект равен нулю.
код в теме
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("%", 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]: ?
Комментарии:
1. Ваша переменная ‘codec’ является глобальной — это задумано? Если нет, попробуйте изменить его на локальную переменную следующим образом:
local codec = DefaultCodec:create()
и такжеlocal char = self.Decode(codec)
.2. @MichalKottman, он был локальным, но я изменил его на глобальный из-за проблемы, с которой я столкнулся, которая не решила проблему. Это довольно странно, поскольку
codec:HasNext()
означает, что кодек не равен нулю, почемуself.Decode
он получаетcodec
значение nil? первая строкаself.decode
isprint...
, которая показывает, что этоnil
3. Вы не показываете реализацию
DefaultCodec
, поэтому трудно догадаться, что на самом деле происходит. Я предполагаю, что вы вызываете это однопоточным способом, без сопрограммирования, поэтому единственное место, гдеcodec
может быть изменено, — это само поDefaultCodec
себе.4. @MichalKottman Я только что сократил код с 1800 строк до 110, что является минимальным подмножеством, и проблема все еще существует. Код может не иметь никакого логического смысла, но игнорируйте это
Ответ №1:
В вашем коде сбой происходит в этой строке:
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
аргумент, либо использовать вызов двоеточия для его автоматической подачи. В вашем code ( self.DecodeCharacter(pbs)
) вы передаете pbs
, что заканчивается как self
в HTMLEntityCodec.DecodeCharacter
, и pbs
заканчивается как nil
. Оба следующих вызова эквивалентны и должны решить проблему:
local char = self.DecodeCharacter(self, pbs)
local char = self:DecodeCharacter(pbs)