On Thu, Jun 6, 2013 at 6:19 AM, Ori Livneh ori@wikimedia.org wrote:
This is a bit annoying, because at first glance "invoke" looks like it's just an alternate syntax for a Lua function invocation, so you expect {{#invoke:Sort|asc|3|1|2}} to be equivalent to sort.asc(3, 1, 2), but that's not the case.
The problem there is what would {{#invoke:Module|func|foo=1|bar=2}} be equivalent to? Maybe Module.func{ foo = 1, bar = 2}, but then your earlier example would have to be sort.asc{ 3, 1, 2 }. And either case your function would be getting a single table with the args as parameters, which is only one step removed from the frame object you actually do get.
Or, you might say, that it would somehow match up the "foo" and "bar" with the parameter names in the function declaration. That would be difficult to accomplish, would complicate modules that need a large number of named parameters, and wouldn't allow for wikitext parameter names that don't match the regex /^[a-zA-Z_][a-zA-Z0-9_]*$/.
Also, having the frame object allows for lazy parsing of the arg values. As you probably already know, if a template argument is not actually used inside the template, it never even gets expanded. The same happens in Scribunto: the wikitext for an argument to #invoke is not actually expanded until it is accessed in frame.args. We couldn't do this if parameters to #invoke were passed directly as parameters to the function.
We'll pretend we're the parser and make our own frame table. Paste the code block above into a module, and type this into the debug console, hitting <return> after each line:
frame = {} frame.args = { 4, 5 }
Better would be to use the method specifically intended for this purpose:
frame = mw.getCurrentFrame():newChild{ args = { 4, 5 } }
That creates a real frame object, so you can test functions that need the various frame methods (e.g. frame:expandTemplate) too.
You can even test things using frame:getParent().args with this method:
parentFrame = mw.getCurrentFrame():newChild{ args = { 'parent', 'template', 'args' } } frame = parentFrame:newChild{ args = { '#invoke', 'args' } }
Note there is a limit on the number of child frames that can be created, to avoid encouraging people to use this relatively-expensive method in actual modules instead of passing arguments directly to other Lua functions. If you hit this limit, just use the debug console's "Clear" button.