seqlua
diff README @ 35:332216604f83
Support special return values of __ipairs metamethod (string as first return value)
author | jbe |
---|---|
date | Sun Aug 24 22:24:19 2014 +0200 (2014-08-24) |
parents | 25cdfe854335 |
children | 4f82d3b3dbd9 |
line diff
1.1 --- a/README Sun Aug 24 22:21:46 2014 +0200 1.2 +++ b/README Sun Aug 24 22:24:19 2014 +0200 1.3 @@ -144,3 +144,119 @@ 1.4 ``seqlua_iterloopauto`` is used. 1.5 1.6 1.7 +Respected metamethods 1.8 +--------------------- 1.9 + 1.10 +Regarding the behavior of the Lua functions and the C functions and macros 1.11 +provided by this extension, an existing ``__index`` metamethod will be 1.12 +respected automatically. An existing ``__ipairs`` metamethod, however, takes 1.13 +precedence. 1.14 + 1.15 +If the ``__ipairs`` field of a value's metatable is set, then it must always 1.16 +refer to a function. When starting iteration over a value with such a 1.17 +metamethod being set, then this function is called with ``self`` (i.e. the 1.18 +value itself) passed as first argument. The return values of the ``__ipairs`` 1.19 +metamethod may take one of the following 4 forms: 1.20 + 1.21 +* ``return function_or_callable, static_argument, startindex`` causes the three 1.22 + arguments to be returned by ``ipairs`` without further modification. Using 1.23 + the C macros and functions for iteration, the behavior is according to the 1.24 + generic loop statement in Lua: 1.25 + ``for i, v in function_or_callable, static_argument, startindex do ... end`` 1.26 +* ``return "raw", table`` will result in iteration over the table ``table`` 1.27 + using ``lua_rawgeti`` 1.28 +* ``return "index", table_or_userdata`` will result in iteration over the table 1.29 + or userdata while respecting any ``__index`` metamethod of the table or 1.30 + userdata value 1.31 +* ``return "call", function_or_callable`` will use the callable value as 1.32 + (function) iterator where the function is expected to return a single value 1.33 + without any index (the index is inserted automatically when using the 1.34 + ``ipairs`` function for iteration) 1.35 + 1.36 +These possiblities are demonstrated by the following example code: 1.37 + 1.38 + require "seqlua" 1.39 + 1.40 + do 1.41 + local function ipairsaux(t, i) 1.42 + i = i + 1 1.43 + if i <= 3 then 1.44 + return i, t[i] 1.45 + end 1.46 + end 1.47 + custom = setmetatable( 1.48 + {"one", "two", "three", "four", "five"}, 1.49 + { 1.50 + __ipairs = function(self) 1.51 + return ipairsaux, self, 0 1.52 + end 1.53 + } 1.54 + ) 1.55 + end 1.56 + print(string.concat(",", custom)) 1.57 + -- prints: one, two, three 1.58 + -- (note that "four" and "five" are not printed) 1.59 + 1.60 + tbl = {"alpha", "beta"} 1.61 + 1.62 + proxy1 = setmetatable({}, {__index = tbl}) 1.63 + for i, v in ipairs(proxy1) do print(i, v) end 1.64 + -- prints: 1.65 + -- 1 alpha 1.66 + -- 2 beta 1.67 + 1.68 + proxy2 = setmetatable({}, { 1.69 + __ipairs = function(self) 1.70 + return "index", proxy1 1.71 + end 1.72 + }) 1.73 + for i, v in ipairs(proxy2) do print(i, v) end 1.74 + -- prints: 1.75 + -- 1 alpha 1.76 + -- 2 beta 1.77 + print(proxy2[1]) 1.78 + -- prints: nil 1.79 + 1.80 + cursor = setmetatable({ 1.81 + "alice", "bob", "charlie", pos=1 1.82 + }, { 1.83 + __call = function(self) 1.84 + local value = self[self.pos] 1.85 + if value == nil then 1.86 + self.pos = 1 1.87 + else 1.88 + self.pos = self.pos + 1 1.89 + end 1.90 + return value 1.91 + end, 1.92 + __ipairs = function(self) 1.93 + return "call", self 1.94 + end 1.95 + }) 1.96 + for i, v in ipairs(cursor) do print(i, v) end 1.97 + -- prints: 1.98 + -- 1 alice 1.99 + -- 2 bob 1.100 + -- 3 charlie 1.101 + print(cursor()) 1.102 + -- prints: alice 1.103 + for i, v in ipairs(cursor) do print(i, v) end 1.104 + -- prints: 1.105 + -- 1 bob 1.106 + -- 2 charlie 1.107 + -- (note that "alice" has been returned earlier) 1.108 + 1.109 + coefficients = setmetatable({1.25, 3.14, 17.5}, { 1.110 + __index = function(self) return 1 end, 1.111 + __ipairs = function(self) return "raw", self end 1.112 + }) 1.113 + for i, v in ipairs(coefficients) do print(i, v) end 1.114 + -- prints: 1.115 + -- 1 1.25 1.116 + -- 2 3.14 1.117 + -- 3 17.5 1.118 + -- (note that iteration terminates even if coefficients[4] == 1) 1.119 + print(coefficients[4]) 1.120 + -- prints: 1 1.121 + 1.122 +