>> On Thu, Feb 16, 2012 at 12:06 PM, Mike Richards <mrichard...@gmx.com> >>> >>> function test() is declared in the current scope, and globally as >>> filterform.test >>> >>> After fiddling around for a bit, it looks like wx.wxEvtHandler:Connect >>> saves upvalues, but not the current function environment (scope), which was >>> set in the call to module(...)
Mike you're right, I was wrong in my first reply. The environment is not saved and the global table is always set as the environment of the Lua event callback function. I haven't thought about this for awhile, but I can't think of any reason not to save it right now, however that code dates from over 5 years ago so I don't remember if it was tried it and it didn't work or what... Here's what's actually done before your Lua event handler function is called, where m_luafunc_ref is the reference to the Lua callback function that's put on the stack. http://wxlua.svn.sourceforge.net/viewvc/wxlua/trunk/wxLua/modules/wxlua/src/wxlcallb.cpp?revision=36&view=markup 191 if (wxlState.wxluaR_GetRef(m_luafunc_ref, &wxlua_lreg_refs_key)) 192 { 193 wxlState.lua_PushValue(LUA_GLOBALSINDEX); 194 if (wxlState.lua_SetFenv(-2) != 0) 195 { 196 // Don't track the wxEvent since we don't own it and tracking it 197 // causes clashes in the object registry table since many can be 198 // created and deleted and the mem address is resused by C++. 199 wxlState.wxluaT_PushUserDataType(event, event_wxl_type, false); 200 wxlState.LuaPCall(1, 0); // one input no returns >>> When the event function is called, the function environment is reset to >>> the global scope, so if you want to reference things you declared in the >>> module scope in the event callback, you have a couple of options: >>> 1. Declare everything as local, which to me is just good practice. >>> 2. Use a fully qualified name (e.g. filterform.test()) >>> 3. Wrap all your calls to wx.wxEvtHandler:Connect like this: >>> >>> function Connect(evthandler, id, func) >>> local environment = getfenv(1) >>> evthandler:Connect(id, >>> function(event) >>> setfenv(1, environment) >>> func(event) >>> end >>> ) >>> end >>> >>> [...] >>> >>> local button = wx.Button([...]) >>> Connect(button, wx.wxEVT_COMMAND_BUTTON_CLICKED, function(event) end) >>> >>> John -- It seems like wx.wxEvtHandler:Connect should do this anyways . . >>> . that is, save the current function environment, and then apply it before >>> calling the callback. I'll have to check a little bit more into 5.2 since get/setfenv are gone, but it looks like all you do is get/set the _ENV variable to get the same behavior. For the callback function, we'd set it as an upvalue to the callback function. http://www.corsix.org/content/look-lua-52-work3 If it's really that simple then yes, we can save the environment and not worry about breaking anything in 5.2, though under the hood it will be implemented differently. If I'm wrong and it can't be made to work in 5.2, then it should be left as is. I'm thinking a little out loud here... the pros of the global + upvalues (current state) is that you always get the same environment so there's no surprises, which is also a downside when you're in a module since you're not in what you thought was the global table. The downside of saving the environment of each Connect() callback is an extra reference to a Lua table. I'll look into it. Regards, John ------------------------------------------------------------------------------ Virtualization & Cloud Management Using Capacity Planning Cloud computing makes use of virtualization - but cloud computing also focuses on allowing computing to be delivered as a service. http://www.accelacomm.com/jaw/sfnl/114/51521223/ _______________________________________________ wxlua-users mailing list wxlua-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/wxlua-users