Skip to content

Access metatables of UserValue and Table #175

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

Closed
hce opened this issue May 14, 2020 · 7 comments
Closed

Access metatables of UserValue and Table #175

hce opened this issue May 14, 2020 · 7 comments
Milestone

Comments

@hce
Copy link

hce commented May 14, 2020

Background: I wanted to implement a library function in rust called "is_callable". It should check whether a Lua value is (a) a function or (b) some Lua object with a metatable that contains a callable __call entry.

I was able to get the metatables of tables from rust/rlua, but not for other types of Lua values...

@jugglerchris
Copy link
Collaborator

Hi,
The metatables of userdata instances are deliberately protected from Lua code (by setting a dummy __metatable entry in the metatable). You could get around it (I think) using debug.getmetatable(), but you'd have to enable the debug library (use Lua::new_with_debug instead of Lua::new); however there's a lot of functionality in debug which can break safety assumptions made by the Rust code.

As far as other types, this is just how Lua is (with the exception of strings, where the metatable points to the _G.string, so "":lower() is the same as string.lower("").

@hce
Copy link
Author

hce commented May 15, 2020

Thank you for your reply! I understand that and don't wish to break rust's safety assumptions.

I just noticed there is no reliable way in Lua to detect whether an object is callable, except by trying and catching exceptions. So, I wish to implement an is_callable function, in rust. But I cannot get the metatable for all Lua types from rust, hence this question whether something could be done about it or if I'm missing something. :-)

@jugglerchris
Copy link
Collaborator

Oops, my apologies! I see that I misread (or didn't quite read properly) your question.

I agree that there isn't a way to do so at the moment (other than the clunky option of loading the debug library and calling debug.getmetatable!), but I don't see a particularly good reason not to add a get_metatable method to AnyUserData. I think @kyren may agree based on the comment on #173 unless I'm missing a reason why it might be unsafe for userdata specifically from the Rust side.

@kyren
Copy link
Contributor

kyren commented May 15, 2020

Actually the metatables for userdata are full of landmines and rlua assumes they're in very particular states to maintain safety, it would be better probably to do something other than give the plain metatable back or it should at least be unsafe.

@jugglerchris
Copy link
Collaborator

Aha, I did wonder. Would something like a has_metamethod(&self, method: MetaMethod) -> bool would be fine?

Or would it be safe enough to have a more general get_metamethod(&self, method: MetaMethod) -> Option<Function>? The worst thing I can think of that you might do with that is call it with inappropriate arguments, but that should just result in an error via FromLuaMulti - I haven't looked into whether metamethods are handled differently from ordinary methods. I may have just made another bad assumption, though!

@hce
Copy link
Author

hce commented Jun 4, 2020

Hmm, for "my" problem the first one would probably suffice.

jugglerchris added a commit to jugglerchris/rlua that referenced this issue Jun 10, 2020
@jugglerchris jugglerchris added this to the Version 1.0 milestone Jul 11, 2021
@khvzak
Copy link
Member

khvzak commented Feb 6, 2024

rlua is going to be deprecated soon and this feature is already supported by mlua

@khvzak khvzak closed this as completed Feb 6, 2024
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

4 participants