Skip to content

Commit

Permalink
Merge pull request #13 from Numynum/feature/call-self
Browse files Browse the repository at this point in the history
fix passing self to metamethods, and add t=self arg syntax
  • Loading branch information
brittyazel committed May 20, 2024
2 parents cfccfe3 + e97163c commit 7379330
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 15 deletions.
23 changes: 12 additions & 11 deletions DevTool.lua
Original file line number Diff line number Diff line change
Expand Up @@ -687,12 +687,17 @@ end

function DevTool:TryCallFunction(info)
-- info.value is just our function to call
local parent
local parent = DevTool.GetParentTable(info)
local fn = info.value
local args = { unpack(self.db.profile.tArgs) }
for k, v in pairs(args) do
if type(v) == "string" and DevTool.starts(v, "t=") then

if type(v) == "string" and v == "t=self" then
if not parent then
local ok, results = false, { "t=self set as argument, but no parent table exists" }
return self:ProcessCallFunctionData(ok, info, parent, args, results)
end
args[k] = parent and parent.value
elseif type(v) == "string" and DevTool.starts(v, "t=") then
local obj = DevTool.FromStrToObject(string.sub(v, 3))
if obj then
args[k] = obj
Expand All @@ -703,14 +708,10 @@ function DevTool:TryCallFunction(info)
-- lets try safe call first
local ok, results = DevTool.TryCallFunctionWithArgs(fn, args)

if not ok then
-- if safe call failed we probably could try to find self and call self:fn()
parent = DevTool.GetParentTable(info)

if parent then
args = { parent.value, unpack(args) } --shallow copy and add parent table
ok, results = DevTool.TryCallFunctionWithArgs(fn, args)
end
if not ok and parent and args[1] ~= parent then
-- if safe call failed we probably could try to find self and call self:fn(), but only if user didn't explicitly specify t=self already
args = { parent.value, unpack(args) } --shallow copy and add parent table
ok, results = DevTool.TryCallFunctionWithArgs(fn, args)
end

self:ProcessCallFunctionData(ok, info, parent, args, results)
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,13 @@ You can specify coma separated arguments that will be passed to any function Dev
be in the form of a `string`, `number`, `nil`, `boolean`, and/or `table`.

- **Note**, _to pass a value with type `table` you have to specify prefix `t=`_.
- **Note**, _to pass the parent table, specify `t=self`_.
- **Note**, _DevTool will automatically try passing `self` as first arg, if the function throws an error_.

Example passing arguments to a function `SomeFunction`:

- FN Call Args: `t=MyObject, 12, a12` becomes `SomeFunction(_G.MyObject, 12, a12)`
- FN Call Args: `t=self, 12, a12` becomes `SomeObject:SomeFunction(12, a12)`
- FN Call Args: `t=MyObject.Frame1.Frame2` becomes `SomeFunction(_G.MyObject.Frame1.Frame2)`

### Chat commands:
Expand Down
8 changes: 4 additions & 4 deletions Utilities/Utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -266,18 +266,18 @@ function DevTool.TryCallFunctionWithArgs(fn, args)
end

function DevTool.IsMetaTableNode(info)
return info.name == "$metatable" or info.name == "$metatable.__index"
return info.name == "$metatable" or info.name == "$metatable.__index" or (info.name == "__index" and info.parent and info.parent.name == "$metatable")
end

function DevTool.GetParentTable(info)
local parent = info.parent
if parent and parent.value == _G then
-- this fn is in global namespace so no parent
if parent and (parent.value == _G or parent == DevTool.list) then
-- this fn is in global namespace, or has no parent
parent = nil
end

if parent then
if DevTool.IsMetaTableNode(parent) then
while DevTool.IsMetaTableNode(parent) do
-- metatable has real object 1 level higher
parent = parent.parent
end
Expand Down

0 comments on commit 7379330

Please sign in to comment.