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

hotswap discards non-table values #18

Open
notwa opened this issue Jan 16, 2017 · 2 comments
Open

hotswap discards non-table values #18

notwa opened this issue Jan 16, 2017 · 2 comments

Comments

@notwa
Copy link

notwa commented Jan 16, 2017

https://github.com/rxi/lume/blob/da0d1bb/lume.lua#L694-L695

    local newmod = require(modname)
    if type(oldmod) == "table" then update(oldmod, newmod) end

currently, if the returned value of a module isn't a table, it (newmod) is discarded.

in my case, my module returns a function, and i expect package.loaded to contain the new value. i am using lurker.lua to trigger hotswapping.

local some_state = 'blah'
local function exec_stuff(name)
  local f = require('stuff_'..name) -- bug: never returns new function value
  some_state = f(some_state)
end

this dirty hack seems to work:

-    if type(oldmod) == "table" then update(oldmod, newmod) end
+    if type(oldmod) == "table" then update(oldmod, newmod) else oldmod = newmod end
@Alloyed
Copy link

Alloyed commented Jan 31, 2017

The problem here is that there's no way to modify existing functions: if you've required and stored the same function somewhere else in the past, that version doesn't get updated with your patch, which means hotswap doesn't actually hotswap anything in that case.

A workaround could be to use __call like so:

local function drop_args(n, f) return function(...) return f(select(n, ...)) end end
return setmetatable({}, {__call = drop_args(1, my_function)})

This is a normal, modifiable table object, so it should work with hotswap, but you can call it as if it were a normal function. That said, if the current behavior is fine with you you can do the same thing manually, without modifying hotswap:

package.loaded[my_mod] = nil
local f = require(my_mod)

@notwa
Copy link
Author

notwa commented Feb 1, 2017

right, afaik you can only emulate updating existing references either by utilizing a wrapper table or by replacing all of an existing table's values. that's why, in my example code, i'm running require each time a function is needed instead of caching it locally. i was expecting this.

what i'm really trying to describe is that i figured hotswap would update non-table return values in package.loaded. this includes returned numeric and userdata values as well.

nulling out the key in package.loaded would work, but that would need to be part of a lurker.lua hook to prevent reloading an untouched file, which might be expensive if the value is needed frequently.

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

No branches or pull requests

2 participants