Markk 2 Report post Posted January 19, 2017 Just made a mock-up addon to show how I have it set up (I've tested this code too and the problem persists) This file loads first based on ordering in .toc: Spoiler MTweaks = {}; function MTweaks:TestFunction(str) if (str ~= nil) then ChatFrame1:AddMessage("|cff408cff[Original] object = |cff7fff7f"..str); else ChatFrame1:AddMessage("|cff408cff[Original] object = |cffab1111nil"); end if str == "TestArg" then -- Stuff would happen... else -- Different stuff would happen... end end function MTweaks:OnLoad() MTweaksEventFrame:RegisterEvent("PLAYER_ENTERING_WORLD"); end function MTweaks:OnEvent() if (event == "PLAYER_ENTERING_WORLD") then MTweaks:TestFunction(); MTweaks:TestFunction("TestArg"); end end This one loads after the above: Spoiler function MTweaks:PostHook(num1, num2, num3, str) if (str ~= nil) then ChatFrame1:AddMessage("|cffffff9a[PostHook] object = |cff7fff7f"..str.."|cffffff9a | "..num1..", "..num2..", "..num3); else ChatFrame1:AddMessage("|cffffff9a[PostHook] object = |cffab1111nil|cffffff9a | "..num1..", "..num2..", "..num3); end if str == "TestArg" then -- Stuff would happen after TestFunction... else -- Different stuff would happen after TestFunction... end end local originalTestFunction = MTweaks.TestFunction; function MTweaks:TestFunction(str) if (str ~= nil) then ChatFrame1:AddMessage("|cffef6030[Altered] object = |cff7fff7f"..str); else ChatFrame1:AddMessage("|cffef6030[Altered] object = |cffab1111nil"); end originalTestFunction(str); MTweaks:PostHook(200, 100, 300, str); end I have an XML too, but it doesn't do anything except create a dummy frame to call the event functions. Here is the output of the chat messages: The second call doesn't pass "TestArg" to the original function, but it does pass it to the post hook. What's going on here? This is not how I expect it to behave. 0 Share this post Link to post Share on other sites
gashole 7 Report post Posted January 19, 2017 (edited) originalTestFunction(_, str); or MTweaks.originalTestFunction = MTweaks.TestFunction; function MTweaks:TestFunction(str) ... MTweaks:originalTestFunction(str); Edited January 19, 2017 by gashole 0 Share this post Link to post Share on other sites
Ike 20 Report post Posted January 19, 2017 (edited) This is a common gotcha for Lua newcomers! Let me explain: When you have a method like this: function SomeTable:SomeFunction(arg) end it is essentially a shorthand for this: SomeTable.SomeFunction = function(self, arg) end In case you have a C++ background, you can see the "self" as the "this pointer" that also gets implicitly passed to a method when you call it. So in order to fix it, you'd have to call the original function like this: local hookedFunction = SomeTable.OriginalFunction; function SomeTable:HookedCall(arg) hookedFunction(self, arg) end Edit: @gashole: No, your first example is wrong. With your code: local Table = {} function Table:OriginalFunction(arg) self:SomeOtherFunction(arg) -- uh oh! end local hookedFunction = Table.OriginalFunction; function Table:HookedCall(arg) hookedFunction(event, arg) end Table.OriginalFunction = Table.HookedCall -- then inside an event handler Table:OriginalFunction("this will break!") Since "Table.OriginalFunction" expects "Table" as its first argument, you'd get an error because "event" isn't said table. Edited January 19, 2017 by Ike 1 Share this post Link to post Share on other sites
Markk 2 Report post Posted January 19, 2017 @Ike so if I changed all functions to SomeTable.SomeFunction = function(arg) , without the self in the parameters, it would work too? It's just the function shorthand that adds the self parameter? 0 Share this post Link to post Share on other sites
Ike 20 Report post Posted January 19, 2017 1 minute ago, Markk said: @Ike so if I changed all functions to SomeTable.SomeFunction = function(arg) , without the self in the parameters, it would work too? It's just the function shorthand that adds the self parameter? Sure, you could also do it like that. Personally, I'd just pass the "self" down to the hook, however. 0 Share this post Link to post Share on other sites
gashole 7 Report post Posted January 19, 2017 30 minutes ago, Ike said: ... Since "Table.OriginalFunction" expects "Table" as its first argument, you'd get an error because "event" isn't said table. I corrected it; however, "event" can be used in this hooked function without error. 0 Share this post Link to post Share on other sites
Ike 20 Report post Posted January 19, 2017 No, the first example is still wrong. Look at my original answer. function Table:Function(arg) end is the same thing as Table.Function = function(self, arg) end Which means that these two are also identical: Table:Function("meow") Table.Function(Table, "meow") Therefore, using the OP's post, the only valid first argument is the table "MTweaks" or its more generic equivalent "self" (since it's used in a "Table:Function" context). While it is true that it wouldn't cause an error in the example Markk posted, it can still later down the line bite him in the ass if he starts calling functions using "self" (e.g. self:Foobar()). In case I don't make much sense (it's 7 am and I haven't had my coffee), here's a link that describes it pretty well: https://coronalabs.com/blog/2015/12/01/tutorial-understanding-the-colon-vs-dot-operator/ 0 Share this post Link to post Share on other sites