Comments (8)
Yes, require
is quite flexible - you can just store your http
table in packaged.loaded["http"]
, and require
will find it.
https://www.lua.org/manual/5.4/manual.html#pdf-require
from rlua.
Yes,
require
is quite flexible - you can just store yourhttp
table inpackaged.loaded["http"]
, andrequire
will find it.
How do i go about implementing it? i tried the following:
let globals = ctx.globals();
let packaged: rlua::Table = globals.get("packaged").unwrap_or(ctx.create_table()?);
let loaded: rlua::Table = packaged.get("loaded").unwrap_or(ctx.create_table()?);
loaded.set("http", http)?;
packaged.set("loaded", loaded)?;
globals.set("packaged", packaged)?;
yet when running the following snippet
http = require("http")
-- define client
local client = http.client()
-- client get request
local res = client:get("https://httpbin.org/get")
print("res 1")
print(res:body())
-- client post request
local res2 = client:post("https://httpbin.org/post", "hi")
print("res 2")
print(res2:body())
-- client do_request
local request = http.request("GET", "https://httpbin.org/get")
local res3 = client:do_request(request)
print("res 3")
print(res3:body())
print("status equality")
print(res:status() == res3:status())
-- top level get function
-- equivalent to creating a client and then doing a get request
local get_resp = http.get("https://httpbin.org/get")
print("get resp")
print(get_resp:body())
i get this error
RuntimeError("[string \"?\"]:1: module 'http' not found:\n\tno field package.preload['http']\n\tno file '/usr/local/share/lua/5.4/http.lua'\n\tno file '/usr/local/share/lua/5.4/http/init.lua'\n\tno file '/usr/local/lib/lua/5.4/http.lua'\n\tno file '/usr/local/lib/lua/5.4/http/init.lua'\n\tno file './http.lua'\n\tno file './http/init.lua'\nstack traceback:\n\t[C]: in ?\n\t[C]: in function 'require'\n\t[string \"?\"]:1: in main chunk")
from rlua.
You've (both) got a small typo, you're meaning to use package.loaded
(not 'packaged').
Though, that is technically not the way you're supposed to do it. As https://www.lua.org/manual/5.4/manual.html#pdf-package.loaded says:
This variable is only a reference to the real table; assignments to this variable do not change the table used by require. The real table is stored in the C registry (see §4.3), indexed by the key LUA_LOADED_TABLE, a string.
(Though, in my experience, despite what it says, it does (at least sometimes) work.)
The proper™ way to make a custom set of packages for require is to create a package.searchers
entry: https://www.lua.org/manual/5.4/manual.html#pdf-package.searchers
from rlua.
Oops, thanks @azdle for the correction, I did indeed mean package.loaded
.
@Yakiyo you don't need to re-set packaged/loaded, you're working with references to the original table. Here's a brief working example:
Lua::new().context(|lua| {
let my_mod = lua.create_table().unwrap();
let hello = lua.create_function(|_, (): ()| {
println!("Hello, world!");
Ok(())
}).unwrap();
my_mod.set("hello", hello).unwrap();
let globals = lua.globals();
let package: Table<'_> = globals.get("package").unwrap();
let package_loaded: Table<'_> = package.get("loaded").unwrap();
package_loaded.set("my_mod", my_mod).unwrap();
let () = lua.load(
r#"
local my_mod = require('my_mod')
my_mod.hello()
"#,
)
.eval()
.unwrap();
});
If you're the code setting up the application, and you're happy to build your modules immediately (i.e. it's not expensive), then I don't see any reason not to do it this way. If you let random Lua code run before then, then package.loaded
may have been changed to point to something completely different.
I agree that accessing it via the registry lua.named_registry_value(rlua::ffi::LUA_LOADED_TABLE)
would be more correct, though ffi
is currently private in rlua
. You could assume it won't change (I don't think it can change within a release), so you could get away with using b"_LOADED\0"
(the value in Lua 5.3/5.4).
Using package.searchers
is probably better for more involved cases, e.g. if you have many modules or some are expensive to initialise, but IMO is overkill when adding a small module or three in a small application.
from rlua.
Oops, thanks @azdle for the correction, I did indeed mean
package.loaded
.@Yakiyo you don't need to re-set packaged/loaded, you're working with references to the original table.
yeah i figured that, i initially did it cz since packaged
was nil, i thought i had to reset it. using package.loaded
works fine for me. i was just trying to write some extension modules that can be used in rlua (repo). i dont suppose there could be a way to use package.searchers
for that. But just for reference, how would u do that with package.searchers? whats the function signature for it?
from rlua.
And another question. i have a lua file, which contains 3/4 different functions. is it in any way possible for me to take and call those functions from the rust side, outside of Lua::context
? the premise of this is, ive got extensions written in lua, where all of them export, for example two funcs, add and sub. i'll load each lua file with a new Lua
instance, and then eval them? but then how do i keep a reference to those funcs, so that i can invoke em when i need. instead of calling lua.context and doing something else.
from rlua.
But just for reference, how would u do that with package.searchers? whats the function signature for it?
According to https://www.lua.org/manual/5.4/manual.html#pdf-package.searchers the searcher is called with the module name, and if successful returns a "loader" function; calling that loader function returns the module. Which sounds complicated for one module, but makes a lot of sense if the searcher is doing something like looking in the filesystem, and returns a function to read and compile that file.
but then how do i keep a reference to those funcs, so that i can invoke em when i need. instead of calling lua.context and doing something else.
You can't call the Lua functions outside of lua.context
- this is part of how rlua
ensures Rust safety. What you can do is use create_registry_value to get back a RegistryKey
which you can store outside of the context function. You can then get the Lua value back efficiently with registry_value later (but still in the context call).
from rlua.
But just for reference, how would u do that with package.searchers? whats the function signature for it?
According to https://www.lua.org/manual/5.4/manual.html#pdf-package.searchers the searcher is called with the module name, and if successful returns a "loader" function; calling that loader function returns the module. Which sounds complicated for one module, but makes a lot of sense if the searcher is doing something like looking in the filesystem, and returns a function to read and compile that file.
but then how do i keep a reference to those funcs, so that i can invoke em when i need. instead of calling lua.context and doing something else.
You can't call the Lua functions outside of
lua.context
- this is part of howrlua
ensures Rust safety. What you can do is use create_registry_value to get back aRegistryKey
which you can store outside of the context function. You can then get the Lua value back efficiently with registry_value later (but still in the context call).
Aight understood. thanks for the help. then ill go ahead and close this as completed.
from rlua.
Related Issues (20)
- Possible bug with __newindex not called on numeric indexing HOT 4
- Question: How to exec multiple things at once? HOT 4
- Segfault on clone of #[repr(C)] userdata subfield HOT 9
- ios build error HOT 7
- examples for error handling HOT 2
- Example for eval return a struct? HOT 1
- Cannot load DLLs in v0.19 HOT 6
- Missing mutable borrows for Table<'lua> HOT 2
- Context.create_sequence_from should support references HOT 1
- Undefined symbol lua_checkstack HOT 8
- Crash on empty source HOT 2
- custom runtime path HOT 3
- [Request] UserData::from_lua HOT 1
- Suggestion: proc_macro for LuaUserDataMethods::add_method HOT 3
- No documentation on how to use LuaRocks with rlua HOT 3
- Rlua + Luarocks Modules -> Fail to load HOT 3
- Memory leak when using system-luajit HOT 2
- Merge with mlua HOT 32
- [Typo] Example says laoded(instead of loaded) HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rlua.