lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


In some situations it would make sense to assign a table to __pairs/__ipairs -- similarly to how you can assign a table or function to __newindex/__index.

Usually if I'm using __pairs/__ipairs I'm working with proxy objects.  I'm creating a ~class~ that constructs proxy objects and I'm defining those within the metatable like so:

__pairs = function (self) return pairs(real_tables[self]) end
__ipairs = function (self) return ipairs(real_tables[self]) end

The proxies are used to retrieve a reference to the table we're really iterating over, and we just call pairs()/ipairs() again.  Using functions here is ideal -- rather than what I'm suggesting -- because the same 2 functions are referenced *once* through that shared metatable on all proxy objects and yet they point to and result in the iteration of their individual real_object tables using the the stock behavior of pairs()/ipairs().  To ...reiterate (haha)... the metatable is shared between all proxy objects.  What I'm suggesting would allow you to create individual metatables for each with a __pairs and __ipairs pointed at real_tables[self].  This would result in more memory usage and is bad.  BAD BAD BAD.

However, for people who aren't constructing many proxy objects and aren't worrying over memory, perhaps this convenience would be nice if you're defining individual objects:

__pairs = { 'a', 'b', 'c' }
__ipairs = { 'a', 'b', 'c' }

This is the same convenience provided by __index/__newindex -- though I imagine that was done for efficiency.  It wouldn't make sense for the many-constructed-proxies situation unless they all acted like references to iterate over a shared table.

So I leave it to the community to decide:

1) Simple enough change to match the semantics of __newindex/__index?
2) Encourages more memory usage by how I explained above.
3) I'm missing something obvious that makes this a bad idea.
4) lfh should get all my presents this year
5) ???
6) This was explained already, search gmane.

The code to be modified would be pairsmeta() in lbaselib.c...  it was only 4 lines and it works as expected :>  (Can someone double-check?)

From 680e6fa0d23e3a90de6401b960975992a8519e46 Mon Sep 17 00:00:00 2001
From: Poggles <sir.pogsalot@gmail.com>
Date: Fri, 20 Dec 2013 09:48:43 +0000
Subject: [PATCH 1/1] allow assigning tables to __pairs/__ipairs

---
 src/lbaselib.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/lbaselib.c b/src/lbaselib.c
index 540e9a5..03ab67a 100644
--- a/src/lbaselib.c
+++ b/src/lbaselib.c
@@ -203,6 +203,10 @@ static int pairsmeta (lua_State *L, const char *method, int iszero,
     else lua_pushnil(L);
   } 
   else {
+    if (lua_istable(L, -1)) {
+      lua_replace(L, 1);
+      return pairsmeta(L, method, iszero, iter);
+    }
     lua_pushvalue(L, 1);  /* argument 'self' to metamethod */
     lua_call(L, 1, 3);  /* get 3 values from metamethod */
   } 
--
1.8.4.2