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 +

Impressum / About Us