# Local functions in Tag Change Script

**URL:** <https://forum.inductiveautomation.com/t/local-functions-in-tag-change-script/59156>\
**Category:** Ignition\
**Tags:** ignition81, scripting\
**Created:** [May 3, 2022, 12:57pm UTC](https://forum.inductiveautomation.com/t/local-functions-in-tag-change-script/59156 "2022-05-03T12:57:50Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![gdube](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/gdube/32/41701_2.png) [@gdube](https://forum.inductiveautomation.com/u/gdube)\
**Post date:** [May 3, 2022, 12:57pm UTC](https://forum.inductiveautomation.com/t/local-functions-in-tag-change-script/59156/1 "2022-05-03T12:57:51Z")

</div>

Hi guys,  
Did anyone notice that system functions aren’t working in locally defined functions in Tag Change scripts? It works in any other context I tried (Gateway message handlers, Perspective scripts, Vision scripts, project scripts).

I wonder why.

Example:  
Gateway Tag Change Script:

- Change Trigger: Value
- Path: [default]Global/test

Script:

```auto
def x():
	system.util.getProjectName()
x()

```

Erorr in logs:  
`NameError: global name 'system' is not defined`

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [May 3, 2022, 1:14pm UTC](https://forum.inductiveautomation.com/t/local-functions-in-tag-change-script/59156/2 "2022-05-03T13:14:21Z")

</div>

Inside your local function then you would have to do an `import system.util`. I can’t give you the technicals why but in a lot of areas of Ignition if you use a local function you end up needing to do that.

Personally I think the best practice, for a multitude of reasons, is to put the entire function logic inside a project script, and then call that function from the tag change script.

I think this get’s rid of the problem you are seeing, and it will make version control easier to do/possible.

---

<div class="post-metadata">

**Author:** ![gdube](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/gdube/32/41701_2.png) [@gdube](https://forum.inductiveautomation.com/u/gdube)\
**Post date:** [May 3, 2022, 1:21pm UTC](https://forum.inductiveautomation.com/t/local-functions-in-tag-change-script/59156/3 "2022-05-03T13:21:18Z")

</div>

Ah, that works! Thank you.

I agree with you, I usually try to put everything in project scripts, but I’ve been dealing with a tiny bit of logic that’s very specify to its context. Thanks again.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [May 3, 2022, 1:26pm UTC](https://forum.inductiveautomation.com/t/local-functions-in-tag-change-script/59156/4 "2022-05-03T13:26:37Z")

</div>

Just `import system` is enough in any of these cases. It is a backwards-compatibility choice IA made some time ago that has gateway project event scripts use a legacy global variable rule. IMNSHO, it should have been ditched for v8.0. Hopefully it’s in the plan for v8.2.

The best work-around is to not write code in event scripts. Write functions in project script modules that accept the event (and any other local variables) as function arguments. So the event script can be a one-line function call. The functions in project script modules will not have the legacy scope issue.

---

<div class="post-metadata">

**Author:** ![nicholas.robinson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nicholas.robinson/32/22188_2.png) [@nicholas.robinson](https://forum.inductiveautomation.com/u/nicholas.robinson)\
**Post date:** [December 13, 2022, 4:34pm UTC](https://forum.inductiveautomation.com/t/local-functions-in-tag-change-script/59156/5 "2022-12-13T16:34:23Z")

</div>

So in a tag change script I cannot do this, correct? The error log indicates that this is not acceptable in a tag change script. Works in the script console but not in a UDT instance.

```auto
writePaths, writeVals = [], []
	
def computePoints(vals, pathFormat):
	"""
	Gets the availability, line count and target
	appends values to writeValues
	appends write path to write path with the specified format
	"""
	global writePaths
	global writeVals
	
    points = ["availableDuration", "lineCount", "targetCount"]

	writePaths += [pathFormat.format(p) for p in points]
	writeVals += [
		sum([v["availableDuration"] for v in vals])/len(vals),
		sum([v["lineCount"] for v in vals]),
		sum([v["targetCount"] for v in vals])
	]

```

Nick

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [December 14, 2022, 1:32am UTC](https://forum.inductiveautomation.com/t/local-functions-in-tag-change-script/59156/6 "2022-12-14T01:32:56Z")

</div>

Not only is that going to be weird in a gateway tag change event, but it begs for disaster if multiple different events call it at the same time (no thread safety). Wherever possible, write pure functions.
