2

How do I invoke a class method using pcall in Lua?

I tried pcall(instance:method, arg) but it doesn't work.
I also tried pcall(instance.method, instance, arg) but that doesn't work either.

I googled for a solution but I couldn't get one.

An example:

local ValueOwnerMap = {}

ValueOwnerMap.__index = ValueOwnerMap

function ValueOwnerMap:create(key_prefix)
    local instance = {}
    setmetatable(instance, ValueOwnerMap)
    instance.key = key_prefix .. ':value-owner-map'
    return instance
end

function ValueOwnerMap:get(value)
    return redis.call('HGET', self.key, value)
end

function ValueOwnerMap:put(value, owner_id)
    return redis.call('HSETNX', self.key, value, owner_id)
end

function ValueOwnerMap:del(value)
    return redis.call('HDEL', self.key, value)
end

local value_owner_map = ValueOwnerMap:create('owner:key')
local success, data = pcall(value_owner_map:put, 'a_value', 'a_owner_id')
5
  • 1
    Show some minimal reproducible example in your question. Do you want pure lua, or C code? Commented Oct 15, 2018 at 11:27
  • pure lua, please Commented Oct 15, 2018 at 11:29
  • Lua is not an object-oriented language. There are several possibilities to emulate object orientation but you have to let us know which one you're using. To this end please add a Minimal, Complete, and Verifiable example to your question. Commented Oct 15, 2018 at 11:30
  • I've added the example Commented Oct 15, 2018 at 11:34
  • pcall(instance.method, instance, arg) but that doesn't work either it works for me Commented Oct 15, 2018 at 14:10

3 Answers 3

8

instance:method(arg) is sugar for instance.method(instance,arg). So try

pcall(value_owner_map.put, value_owner_map, 'a_value', 'a_owner_id')
Sign up to request clarification or add additional context in comments.

2 Comments

Why doesn't lua pcall considers this instance:methoda method?
@wsha, perhaps ask a separate question?
1

The following line replaces the last line of the block in the question. It works.

local success, data = pcall(function () value_owner_map:put('a_value', 'a_owner_id') end)

Thank you all for sharing

Comments

-1

pcall (f, arg1, ···)

Calls function f with the given arguments in protected mode. This means that any error inside f is not propagated; instead, pcall catches the error and returns a status code. lua ref

But Calls for functions in protected mode have some limitations especially when you are using ':' operator 'so-called synthetic sugar' of lua. one way to WAR this limitation is to put inside a function

pcall(function () value_owner_map:put('a_value', 'a_owner_id') end)

This approach also catches the errors as usual:

local ok, msg = pcall(function () error('Phony Error') end)

if ok then 
    print("No error")
else 
    print("Got error".. tostring(msg))
end
-- Result:
-- Got error test.lua:53: Phony Error

7 Comments

The second block of code definitely does not work. Since arguments are existed before functions, a pcall used in that way will not catch errors. Besides,:put does not return a function. The first argument to pcall must be a function.
1. "The second block of code definitely does not work Since arguments have existed before functions" Have you tried it yourself? 2. pcall used in that way will not catch errors. Yes, it will, please test with forced error. 3. Yes, the first argument is a function
> print("result", pcall(error("foo"))) --> stdin:1: foo (no result visible)
> print("result", pcall(function() error("foo") end)) --> result false stdin:1: foo
Please see my answer, i added an example
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.