assign a local variable in the caller’s scope from a function?

110 views
Skip to first unread message

Federico Ferri

unread,
Jun 6, 2025, 10:25:01 AMJun 6
to lu...@googlegroups.com

Hello all,

I’m wondering if there’s any way in Lua to assign a local variable in the caller’s scope from within a function.

To clarify, I’d like to write a helper function like this:

    import("foo", "x")

which would behave as if the caller had written:

    local x = require("foo").x

and I’m curious if there’s any metaprogramming trick, debug API feature, or other mechanism that would make this possible. Has anyone tried this before? Is it fundamentally impossible, or just generally discouraged?

Thanks in advance for any insights.

Best regards,
Federico Ferri

Scott Morgan

unread,
Jun 6, 2025, 10:58:32 AMJun 6
to lu...@googlegroups.com
On 06/06/2025 15:24, Federico Ferri wrote:
> Hello all,
>
> I’m wondering if there’s any way in Lua to assign a local variable in
> the caller’s scope from within a function.
>
> To clarify, I’d like to write a helper function like this:
>
>     import("foo", "x")
>
> which would behave as if the caller had written:
>
>     local x = require("foo").x
>
> and I’m curious if there’s any metaprogramming trick, debug API feature,
> or other mechanism that would make this possible. Has anyone tried this
> before? Is it fundamentally impossible, or just generally discouraged?


If I'm reading you right, I don't think you can do that.

Local variables get turned into a call stack entry after the script is
read and compiled. You can't add them after the read & compile stages,
so nothing can be added at runtime.

Try using luac with the -l option to see what's going on after the
compile stage. You'll note that local var names are not present.

However, something like metalua might be of use to you. Although, I
don't think that's being maintained currently.

Scott

Sainan

unread,
Jun 6, 2025, 11:22:35 AMJun 6
to lu...@googlegroups.com
> However, something like metalua might be of use to you. Although, I
> don't think that's being maintained currently.

I guess this is an instance where I can shill for Pluto, which recently added what is essentially macros via $alias:

package.preload["foo"] = function()
return { x = 1 }
end

$alias import(lib, field) = local field = require(lib).field

import("foo", x)
print(x) --> 1

-- Sainan

Andrey Dobrovolsky

unread,
Jun 6, 2025, 2:40:11 PMJun 6
to lu...@googlegroups.com
Hi all,

Federico Ferri wrote:

>To clarify, I’d like to write a helper function like this:
>
> import("foo", "x")
>
>which would behave as if the caller had written:
>
> local x = require("foo").x

Is it possible to use the wonderful _ENV? Something like:

local import = function(module, index)
local m = require(module)
if m[index] then
_ENV[index] = m[index]
end
return m[index]
end

пт, 6 черв. 2025 р. о 18:22 'Sainan' via lua-l <lu...@googlegroups.com> пише:
> --
> You received this message because you are subscribed to the Google Groups "lua-l" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/suNHF_z9JSC7tVUO2gg5Tq3ABzGxuCLZnwxp0V5-33iT3gnS7fMRwVpj3P2FQwcTdIIOs7yH_yC4V12W3vZV0f2kvE3tFxpg4kjtSFNUtVI%3D%40calamity.inc.

Francisco Olarte

unread,
Jun 8, 2025, 5:01:19 AMJun 8
to lu...@googlegroups.com
On Fri, 6 Jun 2025 at 20:40, Andrey Dobrovolsky
<andrey.dobro...@gmail.com> wrote:
> Is it possible to use the wonderful _ENV? Something like:
...

_ENV is for globals, not locals, see 2.2 in the manual, OP is asking for local.

Francisco Olarte.

Denis Dos Santos Silva

unread,
Jun 8, 2025, 2:43:46 PMJun 8
to lua-l

Andrey Dobrovolsky

unread,
Jun 8, 2025, 7:04:24 PMJun 8
to lu...@googlegroups.com
Really, locals are not part of the environment and can be reached with
debug.getlocal() (find local with distinct name) followed by
debug.setlocal().
Probably the helper Federico Ferri is curious about may look like

local import(module, ...)
local M = require(module)
local selected = {}
for i, name in ipairs{...} do
selected[i] = M[name]
end
return M, table.unpack(selected, 1, #selected)
end

and called like

local mod, f1, f2, f3 = import("my_mod", "f1name", "f2name", "f3name")

нд, 8 черв. 2025 р. о 21:43 Denis Dos Santos Silva <de...@roo.com.br> пише:
> --
> You received this message because you are subscribed to the Google Groups "lua-l" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/9f28e85a-1162-4dcf-bfd3-f7fd3e0f8177n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages