It was thus said that the Great Andrew Starks once stated:
On Wed, Dec 10, 2014 at 8:52 AM, Dirk Laurie <dirk.laurie@gmail.com> wrote:
2014-12-10 16:44 GMT+02:00 Rena <hyperhacker@gmail.com>:
Interesting. Why is __tostring not a core metamethod? The distinction
seems arbitrary to me.
A core metamethod is a fallback. It is called when Lua does not
know what to do, as a last resort instead of throwing an error.
__tostring, __pairs etc are called _instead_ of what Lua knows
to do.
I don't make that distinction, even when I'm reminded that the authors do.
The reason is that, to me, it's meaningless. It works or it does not
work and remembering where it works and doesn't is not something that
I care to invest the time to memorize. At best, I know that whenever I
define `__ipairs`... sort of worry that it may not work, if my table
is handed to a library that may not honor it. To my way of thinking,
there are fields that are attached to metatables that begin with `__`
and end with the name of the method that they modify. Anything beyond
this, to paraphrase the Bible, is complex.
I don't know if this is important enough to bring up in another
thread, but I also don't like the deprecation of `__ipairs`. Whatever
the redundancy it may suffer, it is clear to the writer or reader of
the code that a sequence of key/value pairs, iterated in a consistent
order, is expected. If `ipairs` and `pairs` exist and we allow for a
way to override `pairs`, then consistency would require a
corresponding way to override ipairs.
To recap: in Lua 5.2, ipairs() will attempt to call __ipairs(), which
should return an iterator function, self and an initial value; otherwise,
ipairs() supplies the iterator function, self and an initial value.
The default iterator function goes from index 1 until self[index] returns
nil. I suspect that most (if not all) iterator functions returned from
__ipairs() will do the exact same thing, although it doesn't have to be:
mt =
{
__ipairs = function(t)
local function iter(s,k)
if k == -1 then
return 'one',"ONE"
elseif k == 'one' then
return 'two',"TWO"
elseif k == 'two' then
return 'three',"THREE"
else
return nil
end
end
return iter,t,-1
end
}
x = setmetatable({},mt)
for index,value in ipairs(x) do
print(index,value)
end
one ONE
two TWO
three THREE
At this point, you could use __pairs(). Okay, ipairs() could then check
to see if the initial value returned from __ipairs() is '0' (the default
value if __pairs() doesn't exist) but then, why even bother with __ipairs()?
I suppose it *could* check for an integer initial value, but then, is it
then a sequence as Lua even defines it? Is that an issue? Consistent even?
I know, there's signalling intent. But the default iterator from ipairs()
supports __index, and in Lua, a sequence for ipairs() is defined as a
sequence of integer keys from 1 to n with non-nil values. [1]
I may be misunderstanding this issue and I may be mistaken about 5.3
deprecating it. If I am correct, then it appears to me that the
evolution of Lua is such that eradicating redundancy is valued over
consistency. "Consistency" can be argued about (see math library
change).
If that were true, then ipairs() would be removed as you can always do:
for i = 1 , #t do ... end
-spc (Viewing this from a userdata perspective ... )
[1] I would really expect Thiago, Rena and Coroutines [2] to be upset
over the removal of __ipairs() as (to me) they seem like the type of
people that love overriding how the language works.
[2] What ever happened to Coroutines anyway?