Log in
appy.pod Writing ODT templates The « with » statement

Already introduced in the main section about statements, the with statement deserves more attention.

Recall that its general syntax is the following.

do <document_part> with <variable_name> = <python_expression>

Scopes and variable hiding

Introduced in the previous section about the for statement, the principle of scopes and variable hiding also holds for with statements. If, when defining some <variable_name> via a with statement, this name already denotes a variable in the context, this latter will be hidden in the scope defined by the part of the ODT template being the target of the statement. Once going out of this scope, the global variable will be reified and available again.

Semicolon-separated statements

The statement's syntax as presented at the start of this page is too restrictive: other forms exist. Several statements can be defined on a single line, separated by semi-colons, like in this example.

do section- with var1=computeVar1();var2=computeVar2()

Any number of variables may be defined that way, provided they are all written down in a single line within the LibreOffice comment.

Unwrapping several variables at once

Like iterator variables in for statements, it is possible to unwrap several variables at once in a with statement. Suppose you have this highly interesting function available in the POD context:

def fun(): return (1, 'two', {'three': 3})

You can unwrap, in 3 variables, the 3 elements extracted from the function's result, via this statement:

do table with one, two, three = fun()

The following variables will be added in the POD context.

Variable nameVariable value
one 1
two 'two'
three {'three': 3}

Unwrapping a dynamic number of variables (Python 3 only)

Yet another form of with statement is available (but not in Appy for Python 2), allowing to unwrap a dynamic number of variables. It works by unwrapping a Python dict with a star-based notation. Suppose you have this function available in the POD context:

def moreFun(count):
    r = {}
    for i in range(count):
        r['var%d' % (i+1)] = i
    return r

If you use the following with statement:

do row with *=moreFun(2)

You will define, in the table row where this statement is defined, the following variables.

Variable nameVariable value
var1 0
var2 1

Calling moreFun with count=5 wil produce these variables.

Variable nameVariable value
var1 0
var2 1
var3 2
var4 3
var5 4

The interest of using this form of statement is not necessarily the fact that a dynamic number of variables can de defined. Handling the possible existence or inexistence of some variables in the context would lead to fuzzy POD statements or expressions. Using such statements has sense when used with functions that produce a dict being a kind of mini-POD context, that you may then reuse to inject a set of variables, at various specified places, in one or several POD templates.

Lasting variables: the « with+ » statement

As previously mentioned, the scope of variable·s defined via a with statement is the part of the ODT template being the target of the statement. That being said, an alternate behaviour exists. By using the variant statement named with+, defined variables become lasting: their scope is expanded until the end of the POD template.

If such a statement is defined at the very beginning of a POD template, it is close to defining what could be called global variables.

Note that lasting variables violates the principle of variable hiding: once a variable is hidden by an homonym lasting variable, it will never be available again.

Combine all these forms at will

All the presented forms of with statements can be combined, but not that way:

do text with a, b, * = silly()

Keep in mind to write POD templates being as simple as readable as possible.