Tutorial 4 of 4

Structs across modules

Once a program grows past one file, modules let you keep a struct's definition separate from the script that uses it.

Step 1: Two files, same folder

Create player.flx and main.flx next to each other:

// player.flx
struct Player {
    name;
    health = 100;
    level = 1;

    func takeDamage = define(amount) {
        health -= amount;
    }

    func isAlive = define() {
        return health > 0;
    }
}

func createPlayer = define(name) {
    let p = Player();
    p.name = name;
    return p;
}

let playerVersion = "1.0";

Notice the helper createPlayer(name) function sitting alongside the struct. Since struct constructors bind fields purely positionally, a small factory function like this is a good place to give a field a name at the call site (createPlayer("Rowan") instead of a bare Player("Rowan") that's easy to misread once a struct has several fields).

Step 2: Require it from the entry file

// main.flx
let player = require("player");

let hero = player.createPlayer("Rowan");
output(hero.name);   // "Rowan"
output(hero.health); // 100

hero.takeDamage(45);
output(hero.health);   // 55
output(hero.isAlive()); // true

hero.takeDamage(100);
output(hero.isAlive()); // false

output("Using player module v" + player.playerVersion);

Run main.flx - not player.flx - since main.flx is the one doing the requiring:

$ python -m src.Main run main.flx
Rowan
100
55
true
false
Using player module v1.0

What just happened

  • require("player") found player.flx next to main.flx (no extension in the string - see path resolution) and ran it once.
  • Every top-level name in player.flx - the Player struct, the createPlayer function, and the playerVersion constant - came back as properties on the player module value.
  • The struct itself works exactly the same whether it's defined in the entry file or required from elsewhere.

Where to go from here

Try splitting a second struct into its own file and having player.flx require it in turn - module resolution is always relative to whichever file contains the require call, so this nests naturally. See Example programs for a larger multi-struct program (the inventory management example) to study next.