Home > Software design >  Is it possible in Lua to override a function from a library?
Is it possible in Lua to override a function from a library?

Time:11-05

I'm trying to do a local override of a function so that I can discard the first value returned, and only one value (normally returned as its second value) will be returned by the function.

local r.functionName()
    discardVar,keepVar = r.functionName()
    return keepVar
end

However, when I run this script, I see an error:

'(' expected near '.'

I'm not sure how to make this work. I've only ever written functions without a "." in the function name. I'm not sure if its the right term for it, but I guess that, in this case, "r" would be the library (or maybe 'environment'?) containing the function that I want to locally override.

Basically, the desired outcome would be the function only returns one value instead of two; only the value normally returned as its second return value.

The closest I've gotten to succeeding with this is a legitimate stack overflow, so this seems like the right place to ask about it. :)

r.functionName()
    discardVar,keepVar = r.functionName()
    return keepVar
end

CodePudding user response:

First save the function

local f = r.functionName

Then replace it with your implemention

r.functionName = function()
    local discardVar,keepVar = f()
    return keepVar
end

Note that this will replace the function in the library r too, so if the library itself internally depends on this function name, it can fail.

CodePudding user response:

You can do...

> -- I need to construct r with an example function
> r = {}
> r.functionName = string.gsub
> -- You start here ;-)
> replaced = r
> r = {}
> -- Fill r with replaced key/value pairs one by one
> -- So new references will be created
> -- Means: Changing r not changing replaced ( r ~= replaced )
> for k, v in pairs(replaced) do r[k] = v end
> -- Now replace r.functionName() with a function that calls replaced.functionName()
> r.functionName = function(...)
>> local f, s = replaced.functionName(...)
>> return(s) -- Syntax makes sure that only s will be returned
>> end
> r.functionName(_VERSION, '.', '')
7
> #{r.functionName(_VERSION, '.', '')} -- Number of return values
1
> -- r can than be replaced again (restored/cleanup)
> r = replaced -- Descruct of above r.functionName
> -- Destruct of replaced
> replaced = nil
> collectgarbage('collect') -- Freeing unused memory
  • Related