Thread Tools Display Modes
02-09-12, 05:41 AM   #1
kaels
A Cyclonian
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 46
Help with metatables(?)

2-part question.

(1) Let's say I have an object created as follows:

lua Code:
  1. local object = CreateFrame("Button", name, UIParent, "SecureUnitButtonTemplate")
and a library of functions:

lua Code:
  1. local lib = CreateFrame("Frame")
  2. lib.someFunction = function(stuff)
  3.     DoStuff(stuff)
  4. end

and I want the object to inherit the methods I defined in the library, so that I can call object:someFunction. How would I do that? I know I need to use a metatable, but the metatable examples I've been able to dig up don't seem to make sense.

(2) Let's say my object already has a metatable defined, because the object was constructed in an embedded addon. Is there a way I can let the object inherit my library functions without losing its existing inherited methods?
  Reply With Quote
02-09-12, 08:48 AM   #2
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
You don't need to use a metatable for this.

Code:
object.some_func = lib.some_func
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
02-09-12, 09:11 AM   #3
kaels
A Cyclonian
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 46
If I do that, does that make object.some_func refer to lib.some_func, or does it create a duplicate of some_func for each object?

I know I don't want to do the latter, but I never quite seem to know in Lua when I'm creating something new and when I'm just assigning a pointer.
  Reply With Quote
02-09-12, 10:47 AM   #4
haste
Featured Artist
 
haste's Avatar
Premium Member
Featured
Join Date: Dec 2005
Posts: 1,027
Originally Posted by kaels View Post
If I do that, does that make object.some_func refer to lib.some_func, or does it create a duplicate of some_func for each object?

I know I don't want to do the latter, but I never quite seem to know in Lua when I'm creating something new and when I'm just assigning a pointer.
You are creating a reference to the function:
Code:
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> lib = { some_func = function(self) print(self) end }
> obj = { some_func = lib.some_func }
> = lib.some_func, obj.some_func -- same function
function: 0x214ddd0	function: 0x214ddd0
> lib:some_func() obj:some_func() -- different self
table: 0x214e770
table: 0x214ea70
Frames (and all other UI widgets) already have metatables. It's possible to add methods to it, while still supporting its frame functionality, but you should consider if you really need to do this.

Lua Code:
  1. local frame_metatable = {
  2.    __index = CreateFrame('Button')
  3. }
  4.  
  5. function frame_metatable.__index:tostring()
  6.    return tostring(self)
  7. end
  8.  
  9. local lib = CreateFrame('Button')
  10. lib = setmetatable(lib, frame_metatable)
  11. print(lib:tostring()) -- works

This is pretty much how oUF is implemented.
__________________
「貴方は1人じゃないよ」
  Reply With Quote
02-09-12, 12:18 PM   #5
kaels
A Cyclonian
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 46
Thanks!
  Reply With Quote
02-09-12, 02:28 PM   #6
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,335
Originally Posted by haste View Post
Frames (and all other UI widgets) already have metatables. It's possible to add methods to it, while still supporting its frame functionality, but you should consider if you really need to do this.

Lua Code:
  1. local frame_metatable = {
  2.    __index = CreateFrame('Button')
  3. }
  4.  
  5. function frame_metatable.__index:tostring()
  6.    return tostring(self)
  7. end
  8.  
  9. local lib = CreateFrame('Button')
  10. lib = setmetatable(lib, frame_metatable)
  11. print(lib:tostring()) -- works

This is pretty much how oUF is implemented.
I had developed a way of metatable injection a long time ago that would be more efficient than this. As such, it would create no extra tables/frames in the use of the code itself. The source and destination objects would already exist. The code quoted creates an extra frame and has the CPU transverse an extra table when looking up a value.

This is the code I had in mind for metatable injection.
lua Code:
  1. function InjectMetatable(tbl,meta)
  2.     return setmetatable(tbl,setmetatable(meta,getmetatable(tbl)));
  3. end

Example of usage:
lua Code:
  1. local meta={};
  2. meta.tostring=tostring;
  3.  
  4. local frame=InjectMetatable(CreateFrame("Button"),meta);
  5. print(frame:tostring());
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Help with metatables(?)


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off