Page MenuHomePhabricator

__call metamethod doesn't work on elements of the export table
Open, LowPublic


Create the following as Module:Foo:

local p, mt = {}, {}

function mt.__call(t, frame)
	return 'Hello from the __call metamethod'

p.main = setmetatable({}, mt)

return p

From the sandbox, =p.main(mw.getCurrentFrame()) correctly displays "Hello from the __call metamethod". From wikitext, however, {{#invoke:Foo|main}} displays a script error that p.main isn't a function.

Version: unspecified
Severity: trivial



Related Objects

Event Timeline

bzimport raised the priority of this task from to Low.
bzimport set Reference to bz66278.
bzimport added a subscriber: Unknown Object (MLST).
Anomie added a comment.Jun 6 2014, 8:55 PM

What would be the advantage of allowing #invoke to call a table via the __call metamethod, instead of just using a function?

Functions seem like they would be much less confusing to on-wiki module authors than tables-that-can-be-called.

Take this module, for example:
local p = {}

p.continents = {
na = { area = 24490000, pop = 542056000 },
sa = { area = 17840000, pop = 392555000 },
antarctica = { area = 13720000, pop = 4490 }

p.oceans = {
atlantic = { area = 82400000, volume = 323600000 },
pacific = { area = 165250000, volume = 714000000 }

local mt = {}

function mt.__call(t, frame)
for _,v in ipairs(frame.args) do

		t = t[v]

return t

for _,v in pairs(p) do
setmetatable(v, mt)

return p

This module allows other modules to retrieve data via "foo =", and wikitext to retrieve data via "{{#invoke:Foo|continents|na|area}}".

Anomie added a comment.Jun 9 2014, 4:19 PM

OTOH, you could as easily write that with a function getContinent, and at the same time avoid confusing people into thinking they could do "{{#invoke:Foo|bar|baz}}" for any random table that is included in 'p'.

For that matter, returning random tables in 'p' may not be the greatest idea; see bug 48393 for example.

Jackmcbarn updated the task description. (Show Details)Jun 3 2016, 10:10 PM