Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

class() calls constructor of previously created class #9

Closed
asb opened this issue Apr 5, 2011 · 6 comments
Closed

class() calls constructor of previously created class #9

asb opened this issue Apr 5, 2011 · 6 comments

Comments

@asb
Copy link

asb commented Apr 5, 2011

I recently updated from a a previous Penlight version to latest git head and have encountered a bug which breaks my code using class() from pl.class. Hopefully this example demonstrates the problem - I don't believe there's any reason for A's constructor to be called when defining class B.

$ cat t.lua
class = require("pl.class").class

A = class()
function A:_init(mandatory)
  assert(mandatory, "tried to initialise instance with no arg")
end
B = class()

$ lua t.lua
lua: t.lua:5: tried to initialise instance with no arg
stack traceback:
  [C]: in function 'assert'
  t.lua:5: in function '_init'
  ./pl/class.lua:18: in function 'call_ctor'
  ./pl/class.lua:84: in function 'class'
  t.lua:7: in main chunk
  [C]: ?
@stevedonovan
Copy link
Contributor

Yeah, I see exactly what you mean - it's a sneaky feature. It allows a certain lazy style of inheritance; base ctor takes a string; subclasses can be made without explicit ctors, confident that the base ctor will be passed the string. Well, if you remember to pass it, of course - nasty stuff to document! I am tending towards 'everything is explicit' these days so maybe it should just go.

@asb
Copy link
Author

asb commented Apr 5, 2011

But A:_init is an instance constructor - why would it ever be correct that it would be called when creating a new class? Have I not 1) created a new class and assigned it to A. 2) defined _init for class A and 3) created a new class and assigned it to B? Why should action 3) results in A:_init being called?

@stevedonovan
Copy link
Contributor

Sorry, I misread you - I tried exactly the code you gave, and yes, I get also get a ridiculous result! Genuine, first class bug!

@stevedonovan
Copy link
Contributor

This is very interesting - pl.class is one of the modules that changed - require 'pl.class' returns the actual class object. So if were

    class = require ('pl.class')

then things work fine - which is why I didn't see the problem at first. By some horrible fluke class.class exists and is a function, so everything looks hunky dory until it falls over.

@asb
Copy link
Author

asb commented Apr 6, 2011

Ah I see, the previous version of Penlight I was using exported something like class, Map, and Set. But as you say it just returns pl.class now, so when I do require("pl.class").class the __index on the returned pl.class is called. This is a case of programmer error resulting from API breakage that probably turned out to cause more trouble than intended (due to the __index on pl.class). I'll mark it closed.

@asb asb closed this as completed Apr 6, 2011
@stevedonovan
Copy link
Contributor

What I will do is detect this particular case and issue a stern warning, otherwise it is going to cause confusion! (The other option is to regard it as an error)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants