help request: when are class instance properties available?

I have a problem with some simple code.
i want to list all the functions of an object b defined from a class Myclass.
My understanding is that the functions of Myclass are declared in b once they have been called once from b. This is the class extension mechanism.
If you run my code, you will see the red circle on the screen, so b:draw() has been called, so b.draw is defined.
If you tap on the ‘show b1 functions’ button nothing shows up.
Why is it so???
It doesnt fit with my understanding of lua dynamics.
I have an explanation: when the function inside parameter is declared, b.draw hasnt been called yet, so at this moment it is not known. b is duplicated in the upvalues of the function. But is is quite a weird result, because that means the b in the function is not the same as the b used later, although it has the same adress…
1/ Can anyone confirm or not this this the correct explanation?
2/ Then this is a nasty bug… what ‘best practice’ would you advise to avoid such things to happen? In complex code, it will be very difficult to find out, so i need a design rule just to make sure this never happens again. What should it be?
Thanks for you help.

Just to check the code works, if you tap on the ‘show Myclass functions’ button you get all the expected functions.
here is the code

Myclass = class()
function Myclass:init()
end
function Myclass:draw()
    fill(255, 0, 0, 255)
    ellipse(300,300,50)
end
list = {}
function menu()
    b = Myclass()
    table.insert(list,b)
    parameter.action("show b1 functions", function()
        print("b1 functions")
            for key,val in pairs(b) do
                if type(val) == "function" then print(key) end
            end
    end)
    parameter.action("show Myclass functions", function()
        print("Myclass functions")
            for key,val in pairs(Myclass) do
                if type(val) == "function" then print(key) end
            end
    end)
end
function setup()
    menu()
end
function draw()
    for i,o in pairs(list) do o:draw() end
end

i assume all this would not happen if parameter.action would accept more than 2 parameters, like tween.delay, then b could be in the execution parameters instead being in the closure?
Then, maybe @Simeon what about extending parameter.action so it accepts more parameters to be passed to the callback function?

@Jmv38 the functions aren’t defined in your class instances, because the table created by class() is used for all instances. So you can list all the functions in b by iterating over b.__index instead — of course, individual member variables (ex. self.x = 5) would be listed as entries on b.

ok thanks, i’ll try that.

Trying to list obj.__index works great in my above example.
but it still doesnt work in my real project. The draw function is not in the list of functions of obj nor obj.__index. Although just before that i can print obj.draw adress! This is driving me nuts.
When i put in a row all the hours i have spent because of special behavior of class(), i wonder if it would not be better to use the extend() function (@toadkick source : direct shallow copy of all field) instead: then everything would be clean and simple.

ok i found it.
@Briarfox you better read that! I dont know which version of eventMngr() you are using, but mine was a class()… Then using extend() to copy the fields to an object also copies the __index and isA objects! Then it is a mess because it overwrite these original from the object extended. Aaaaargh!
so i have cured it by defining the eventMngr as a {}, not as a class().
As usual, the bug was in my code, not in lua. But it is damn tricky to use those class() anyway…

@Jmv38 Thanks for the heads up I’ll change my version as well. I liked your Queue idea (fifo) so I’ve added the ability to set it up as either queue or stack.

@Briarfox about the fifo, here is how i have implemented (just to let you know).
By default i do fifo. But i can call executeNextCallBeforeOthers() then the next on() only is written at the beginning of the list. I did that cause i didnt want to add another parameter to the on() function.

EventMngr = {}

local fifo = true -- first in (to register) first out (to be triggered)
function EventMngr:on(name, fn, obj)

    if not self.events then self.events = {} end -- init event table if does not exist
    if not self.events[name] then self.events[name] = {} end -- init this event name
    
    local new = true -- confirm it is a new request
    for i,fa in ipairs(self.events[name]) do
        if fa.func == fn and fa.obj == obj then new = false end
    end
    
    local p -- insertion point in the table
    if new then 
        if fifo then p = #self.events[name] +1 else p = 1 ; fifo=true end
        table.insert(self.events[name], p, {func = fn, obj = obj }) 
    end

    return self
end

function EventMngr:executeNextCallBeforeOthers()
    fifo = false
end