3

I'm trying to implement support for IronPython in a section of our application that uses scripting and currently supports a number of existing languages such as Lua.

The scenario is that we need to both support return values from scripts (using the language's return or equivalent syntax) and also read on exit, and write before execution variables to be used throughout the script.

The problem I'm having with IronPython is that it seems to not allow use of return in a script outside of a function. I can therefore wrap all scripts in a function, though this is messy as I then have to indent all the code, whilst that's not a massive problem in itself it appears that any variables referenced in the script are treated as function scope local variables, and that the GetVariable/SetVariable methods do not allow me to specify these as globals thus the now method wrapped script fails as it cannot find the variables set by GetVariable and SetVariable.

So for example taking the script:

integerVar = integerVar + 10
stringVar = stringVar + " modified"
return true

Will not work directly, because the return statement fails due to not being in a method. Wrapping in a function:

def run():
    integerVar = integerVar + 10
    stringVar = stringVar + " modified"
    return true

Fails when the method is called with "Local variable 'integerVar' referenced before assignment", despite being set previously with SetVariable on the scope.

Is there any way I can execute IronPython scripts in a way that allows me to both obtain any value returned from a return statement, and to be able to both set values to be manipulated by the script prior to execution, and obtain their values post execution?

Xefan
  • 645
  • 1
  • 12
  • 26
  • Have you read this [answer](http://stackoverflow.com/a/26452775/215576)? It has a [MCVE](http://stackoverflow.com/help/mcve) that you can use as a starting point. As for the script's "return", you can use the last statement of the script as a return value instead of using `return` (ex.: `True` instead of `return True`). If you really want to use `return` you will have to wrap it in a function as you've seen and call the function at the end (so the interpreter will run it). – ssarabando Jun 28 '16 at 14:07
  • That answer is currently pretty much exactly how I do things, but when wrapping a method I have the aformentioned problem of variables accessed with Set/GetVariable not being accessible in a wrapped method. I do need to retain the return function keyword for the simple fact that external clients will be writing scripts and would typically expect to be able to return results this way. – Xefan Jun 28 '16 at 14:28
  • With those constraints, you could prepend each user script with the string `"def _udf():"` (don't forget a newline after the `:`), indent all the user's code, and then append `"_udf()"` (again, with a newline at the start). That'll make the `Execute` method of the engine to return whatever the script's return value is. As for the variables, I can only see you getting those if you declare them as `global` inside the function body... – ssarabando Jun 28 '16 at 15:05

1 Answers1

0

You need to use the "global" keyword inside your function. Example is as follow:

def run():
    global intergerVar
    integerVar = integerVar + 10
    stringVar = stringVar + " modified"
    return true

For more example and information you can refer to this thread.

wiz_lee
  • 778
  • 9
  • 13