Это проблема с переменной областью lua (и как ее можно решить)? - PullRequest
0 голосов
/ 17 октября 2011

Очень странная ошибка, показывающая, что объект равен нулю.

код в теме:

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

END OF FILE

Консольный вывод:

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 Ответ

4 голосов
/ 17 октября 2011

В вашем коде сбой происходит по этой строке:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...