Thread Tools Display Modes
04-29-17, 08:01 AM   #1
SuperRookie
A Deviate Faerie Dragon
Join Date: Apr 2017
Posts: 11
function call on storing a value into the table

Sorry for spamming, but since the question is totally different the previous topic, I had to start a new thread

So, I'm trying to make a table that calls a function when a new value is being stored into the table.

E.g.
Code:
table[0] = "value"

or

table.insert(table, "value")
I've done some research and using metatable and its '__settable' method would do a trick, but I could've not found a working example for this.

Does anyone have any idea regarding this?
  Reply With Quote
04-29-17, 08:26 AM   #2
SuperRookie
A Deviate Faerie Dragon
Join Date: Apr 2017
Posts: 11
btw, metamethods doesn't work with table functions

+

Maybe '__index' is the one that I was looking for...

Last edited by SuperRookie : 04-29-17 at 08:56 AM.
  Reply With Quote
04-29-17, 10:05 AM   #3
Ketho
A Pyroguard Emberseer
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,026
Originally Posted by SuperRookie View Post
So, I'm trying to make a table that calls a function when a new value is being stored into the table.

E.g.
Code:
table[0] = "value"

I could be wrong, but it's something like this with __newindex
Lua Code:
  1. local mt = setmetatable({}, {__newindex = function(t, k, v)
  2.     rawset(t, k, v)
  3.     print(k, v)
  4. end})
  5.  
  6. mt[7] = "Hello World"
  7. -- prints 7, "Hello World"

Last edited by Ketho : 04-29-17 at 10:08 AM.
  Reply With Quote
04-29-17, 04:36 PM   #4
SuperRookie
A Deviate Faerie Dragon
Join Date: Apr 2017
Posts: 11
Hi Ketho,

Awesome!

thx for letting me know !!

* EDIT: One problem with '__newindex' is that if the key already exists, it doesn't call its '__newindex' metamethod as its name indicates.

So, the following would call '__newindex' only once, but for my case, I need a method that runs every single time when there is a change within a table.

Lua Code:
  1. local t = {}
  2.  
  3. local mt = {
  4.     __newindex = function(table, key, value)
  5.         print("__newindex called")
  6.  
  7.         rawset(table, key, value)
  8.     end,
  9. };
  10.  
  11. setmetatable(t, mt)
  12.  
  13. t[5] = 10 -- '__newindex' metamethod called & print
  14.  
  15. t[5] = 15 -- '__newindex' metamethod not called

Last edited by SuperRookie : 04-29-17 at 07:43 PM.
  Reply With Quote
04-29-17, 11:16 PM   #5
lightspark
A Rage Talon Dragon Guard
 
lightspark's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2012
Posts: 341
Originally Posted by SuperRookie View Post
Hi Ketho,

Awesome!

thx for letting me know !!

* EDIT: One problem with '__newindex' is that if the key already exists, it doesn't call its '__newindex' metamethod as its name indicates.

So, the following would call '__newindex' only once, but for my case, I need a method that runs every single time when there is a change within a table.
You could try using metatable as a proxy then.

Lua Code:
  1. local _T, T = {}, {} -- table, proxy
  2. setmetatable(T, {
  3.     __newindex = function(_, k, v)
  4.         print("__newindex")
  5.  
  6.         _T[k] = v
  7.     end,
  8. })
  9.  
  10. T[5] = 10 -- "__newindex"
  11.  
  12. T[5] = 15 -- "__newindex"

Here's a good read: https://www.lua.org/pil/13.4.4.html
__________________

Last edited by lightspark : 04-29-17 at 11:44 PM.
  Reply With Quote
04-29-17, 11:50 PM   #6
SuperRookie
A Deviate Faerie Dragon
Join Date: Apr 2017
Posts: 11
Haha! You are genius, lightspark

That's exactly what I was looking for

So, table 'T' is actually a fake while '_T' is the actual table that holds elements, right?

That's just genius!
  Reply With Quote
04-30-17, 12:07 AM   #7
lightspark
A Rage Talon Dragon Guard
 
lightspark's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2012
Posts: 341
Originally Posted by SuperRookie View Post
Haha! You are genius, lightspark

That's exactly what I was looking for

So, table 'T' is actually a fake while '_T' is the actual table that holds elements, right?

That's just genius!
Yeah, T is a proxy that's used to track read (__index) and write (__newindex) accesses, _T is our storage

I use something similar in one of my addons, but all credit goes to the author of the article I linked.
__________________

Last edited by lightspark : 04-30-17 at 12:11 AM.
  Reply With Quote
04-30-17, 12:25 AM   #8
SuperRookie
A Deviate Faerie Dragon
Join Date: Apr 2017
Posts: 11
Originally Posted by lightspark View Post
Yeah, T is a proxy that's used to track read (__index) and write (__newindex) accesses, _T is our storage

I use something similar in one of my addons, but all credit goes to the author of the article I linked.
Haha!

All good!

Thanks for the reference (a link) as well
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » function call on storing a value into the table


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