lua-users home
lua-l archive

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


On Fri, Nov 18, 2022 at 1:25 AM Sean Conner <sean@conman.org> wrote:

>   The difference is of opinion.

In an email discussion, all we have is opinions, quantized and character-coded.

>  I do not think this is obviously wrong, nor
> have I been convinced that it's even wrong.  I think that monkeypatching [1]
> is wrong, and I will try to disuade people from doing it ("play stupid
> games" and all that), but I do admit that it is sometimes desirable to do
> [2] and won't try to make it impossible.

I never said that monkey patching in general was good or bad. This is
"the circumstances that make that possible" of my previous message.
But monkey patching of __gc specifically of userdata is obviously
wrong.

As I also said in the previous discussion, __gc (of userdata) is very
different from all the other metamethods. The latter are optional and
no major harm will happen if they are "monkey-patched" (away). Not so
with __gc (of userdata). Some years ago Lua's authors subscribed to
that, too.

Lua 4.0 was released 20 years ago. It was the last version before
metatables. Instead it had tags and tag methods. And here is what its
manual states:

gettagmethod (tag, event)
Returns the current tag method for a given pair (tag, event). This
function cannot be used to get a tag method for the ``gc'' event.
(Such tag methods can only be manipulated by C code.)

settagmethod (tag, event, newmethod)
Sets a new tag method to the given pair (tag, event) and returns the
old method. If newmethod is nil, then settagmethod restores the
default behavior for the given event. This function cannot be used to
set a tag method for the ``gc'' event. (Such tag methods can only be
manipulated by C code.)

Less than three years later, Lua 5.0 was released. Judging from its
manual, it was possible to change __gc in a metatable once the
metatable is obtained, which was also not restricted by default. This
is in sharp contrast with the previous version.

Why the change? I have looked for an answer in "The Evolution of Lua".
It does describe the reasons why tags and tag methods were traded for
metatables, and also touches upon the changes in userdata and garbage
collection between 4.0 and 5.0, but, I think, it says nothing that
would justify the ability of the user code to change the __gc method
of userdata. I believe it was a mistake, possibly guided by the
conceptual generality or elegance of the approach.

That it was a mistake was recognized no later than in 5.2 (some 8
years after). Before that, not only was __gc method freely changeable
by the user, but the changes were also taking effect at the
finalization time. 5.2 made those changes take no effect on EXISTING
data, but still let them have effect on FUTURE data (with the same
metatable). So a prudent library author can proactively restore the
__gc method in the metatable before it is associated with a new
userdatum, or bite the bullet and roll out the whole nine yards of
__metatable machinery, but it looks like few library authors are aware
of the issue, and some of those who are, such as the authors of the
built-in IO library, just look the other way.

Cheers,
V.