On Thu, Jun 6, 2013 at 6:19 AM, Ori Livneh <o...@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.


-- 
Brad Jorsch
Software Engineer
Wikimedia Foundation

_______________________________________________
Wikitech-l mailing list
Wikitech-l@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/wikitech-l

Reply via email to