Use include files when you want to reuse Expr code from another file.
A good include file can hold functions, classes, constants, or small helper code that is shared by several scripts. This keeps the main script shorter and makes common code easier to maintain.
Create a file with reusable code.
Example file:
// math_helpers.expr function ToolRadius(diameter) { return diameter / 2; } function Area(width, height) { return width * height; }
This file only defines functions. It does not run a job by itself.
Use `include` at the top level of another script.
include "math_helpers.expr" radius = ToolRadius(6); area = Area(40, 25); print(radius); print(area);
After the include, the functions from `math_helpers.expr` are available in the current script.
The include statement can use a semicolon, but it does not require one.
include "math_helpers.expr"; include "other_helpers.expr"
`include` is a top-level statement.
Use it at the script level:
include "math_helpers.expr" print(ToolRadius(6));
Do not put it inside `if`, `while`, `for`, functions, or classes.
if (1) { include "math_helpers.expr" // error }
If a script needs different behavior, include the needed files first, then choose what to call with normal `if` logic.
For reusable files, prefer including with `as`.
include "math_helpers.expr" as Math radius = Math::ToolRadius(6); area = Math::Area(40, 25);
The alias keeps included names grouped. This helps avoid name collisions when several libraries define similar function or class names.
Without an alias, included functions and classes are added directly to the current namespace:
include "math_helpers.expr" radius = ToolRadius(6);
This is acceptable for small scripts, but aliases are better for shared libraries.
Include files can also define classes.
Example file:
// probe_job.expr class ProbeJob() { safe_z = 5; feed = 100; function SetFeed(value) { feed = value; } function Run() { return safe_z; } }
Use it from another script:
include "probe_job.expr" as Probe job = Probe::ProbeJob(); job.SetFeed(120); result = job.Run();
Classes are often the best way to keep related data and workflow code together.
A reusable include file should usually define functions and classes, not start doing work immediately.
Good include file:
// probe_math.expr function ClearanceZ(surface_z, clearance) { return surface_z + clearance; }
Risky include file:
// probe_run.expr safe_z = 5; feed = 100; print('probing now');
Top-level statements in an included file run each time the file is included. That can be useful for a runnable script, but it is usually not what you want in a reusable library.
Use a path without a leading dot for a file beside the current source script.
include "math_helpers.expr" as Math include "probe_steps.expr" as Steps
Use `./` for shared libraries stored in the profile folder.
include "./lib/probing/probe_job.expr" as Probe include "./lib/atc/tool_change.expr" as ATC
This is important: in Expr path rules, `./` means profile-relative, not source-relative.
Use How relative paths work when you need exact path behavior.
If you run Expr from MDI or another host input, you can include a script file and call code from it.
=include "./lib/probing/probe_job.expr" as Probe job = Probe::ProbeJob(); job.Run();
In MDI, the leading `=` tells the host to evaluate the input as Expr instead of G-code.
For multi-line MDI input, put the include first so the definitions are available to later lines.
Including the same file more than once is allowed, but it is not treated as `pragma once`.
This means:
For simple scripts, include each library once near the top of the file.
Do not make two files include each other.
Avoid this:
A.expr includes B.expr B.expr includes A.expr
Prefer this:
probe_job.expr defines ProbeJob probe_dialog.expr defines ProbeDialog probe_plate.expr includes both and connects them
The top-level script should connect independent include files together.
For a normal reusable include:
Example:
include "./lib/probing/probe_job.expr" as Probe job = Probe::ProbeJob(); job.SetFeed(120); result = job.Run();