lunarmodules / Penlight

A set of pure Lua libraries focusing on input data handling (such as reading configuration files), functional programming (such as map, reduce, placeholder expressions,etc), and OS path management. Much of the functionality is inspired by the Python standard libraries.
https://lunarmodules.github.io/Penlight/
MIT License
1.91k stars 239 forks source link

classname:_init is inherited exactly one level and that is confusing #288

Open mcclure opened 5 years ago

mcclure commented 5 years ago

I am a longtime user of Penlight, I make especially heavy use of the class module.

I found something today. I check out a copy of Penlight 1.6.0. I run lua5.1 and run the following:

> class = require("pl.class")
> class.A()
> function A:_init(x) print(x) end
> A(3)
3
> class.B(A)
> B(4)
4
> class.C(B)
> C(5)
> 

B inherits from A, C inherits from B. Only A has an explicit constructor. B inherits A's constructor, but C does not inherit a constructor. This feels like a bug, it's not in the documentation. In my testing, methods other than _init can be implicitly inherited multiple levels deep without problems.

My expected behavior is that if I don't override the constructor, it should be inherited as many levels deep as the hierarchy goes.

mcclure commented 5 years ago

Looking at the class.lua code, the problem seems to be that call_ctor() walks all the way up the chain looking for a _init to call, but mt.__call explicitly checks only rawget(c,'_init') and rawget(base,'_init') and then gives up.

Is there some reason _init could not be "fat inherited" into the class object the same way methods are?

alerque commented 5 years ago

Is there any progress on including this? I just spent quite a while bashing my head against an issue that turns out to have it's root in my expectation of this exact things being fixed.