Solarus-Games English Forum

Solarus => Development => Topic started by: Zefk on May 05, 2017, 09:30:23 AM

Title: [Solved]pcall metatable?
Post by: Zefk on May 05, 2017, 09:30:23 AM
How does a pcall or xpcall error message work with a metatable?
http://www.solarus-games.org/doc/latest/lua_api_main.html#lua_api_main_get_metatable
Title: Re: pcall metatable?
Post by: Christopho on May 05, 2017, 10:01:00 AM
What do you mean?
Title: Re: pcall metatable?
Post by: Zefk on May 05, 2017, 10:44:17 AM
If the function fails, then I'd like to give a custom message.

Code ( lua) Select
function myfunction()
   n = n/nil
end

if pcall(myfunction) then
   print("Success")
else
   print("Failure")
end
Title: Re: pcall metatable?
Post by: Christopho on May 05, 2017, 11:21:31 AM
Your code is a correct way to catch errors.
But you were talking about metatables in your first message, what do you want to know exactly?

I don't know if it answers your question, but sol.main.get_metatable() returns nil if the parameter is an unknown type name. It will only throw an error if the parameter is missing or is not a string.
Title: Re: pcall metatable?
Post by: Zefk on May 05, 2017, 12:35:26 PM
Is it possible to pcall something like the following?

example.lua

Code ( lua) Select


local metatable = sol.main.get_metatable("custom_entity")

function metatable:example()
  --some code
end



main.lua
Code ( lua) Select
require(scripts/example.lua)

custon entity:

Code ( lua) Select
entity:example()

if pcall (example) then

  print("success")

else

   print("fali")

end

Title: Re: pcall metatable?
Post by: Diarandor on May 05, 2017, 01:31:16 PM
Note that your "example" variable, inside pcall, is nil. And that space between pcall and the parenthesis may give an error, but I am not sure.
Title: Re: pcall metatable?
Post by: Christopho on May 05, 2017, 02:05:09 PM
Ok, so your question is actually independent from metatables or Solarus, it is about the passing a value of type function vs calling a function.
Code ( lua) Select

function metatable:example()
  --some code
end


This defines a field "example" (of type function) on the object "metatable", and not an "example" global value.

Which means that you can call it like this, assuming you  have an entity called my_entity:
Code ( lua) Select
my_entity:example()
and not like this
Code (lua) Select
example() -- Does not work: example is nil

If you want to make a value of type function instead of doing the call entity:example(), just wrap the call it in a function:
Code (lua) Select

local function f()
  my_entity:example()
end

Then it is a value of type function (and not a function call anymore, this is the trick!) so you can pass it to anything that wants a value of type function, like pcall, sol.timer.start, etc.
Code (lua) Select

local success = pcall(f)
if success then
  ...
else
  ...
end


You can even keep it anonymous if you prefer:
Code (lua) Select

local success = pcall(function()
  entity:example()
end)
if success then
  ...
else
  ...
end
Title: Re: [Solved]pcall metatable?
Post by: Zefk on May 05, 2017, 03:10:23 PM
@Christopho
That was a perfect explanation. Thank you Christopho!