Skip to content
Kavachकवच

Modules: pub

● Intermediate3 min

pub makes a type, a function or a field visible to other modules. Without it, only the module itself sees it.

A record with a private field can be made only in its own module, so that module stays in charge of what the field holds. Another module that tries is refused:

use billing.invoice.{Invoice}

fn main() {
    const inv = Invoice(id: 7, total: 1, note: "free!")
    print(inv.total)
}

The compiler refused the program:

kavach run

error: `Invoice` has a private field (`note`), so only module `billing.invoice` can create one: add a `pub fn` there that makes it (spec 10.1)
src/main.kav and 1 more file: Kavach code, then what running it prints

The fix is the one the message gives: a pub fn in billing.invoice that makes an Invoice, as create does.

An extend in the same package

An extend of a type in another file of the same package counts as the type's own module. It may read, change and build the type's private fields, so a type's methods can be spread over files without making its fields pub:

use moves

/// A wallet whose fields only its own package may touch.
pub type Wallet {
    balance: Int = 0
    payments: Int = 0
}

The program ran and printed:

kavach run

2 payments, 150 in total0 payments, 0 in total
src/lib.kav and 2 more files: Kavach code, then what running it prints

An extend in another package sees only pub fields.

tested

Methods are private to their package

A method without pub can be called anywhere in its own package, so the package's modules can share helper methods without making them part of what it offers. Here pricing calls tax, and the program that uses shop can't:

use shop.{Order}

fn main() {
    const o = Order(total: 200)
    print(o.due())
    print(o.tax())
}
src/main.kav: Kavach code
terminal
kavach run src/main.kav
error: the method `tax` of `Order` is private to package `shop`: mark it `pub` there to call it here (spec 10.1)
 --> src/main.kav:6:13
  |
6 |     print(o.tax())
  |             ^^^
  • The same holds on the type: Order.blank() is refused outside shop when blank isn't pub.
  • A method an interface asks for can be called wherever the interface can, pub or not.
tested

Agents too

An agent is a declaration like any other. Mark it pub, and other modules can start it and call its handlers:

pub agent Picker {
    on pick(items: [Int], at: Int) -> Int {
        items[at]
    }
}

The program ran and printed:

kavach run

30
src/bots.kav and 1 more file: Kavach code, then what running it prints

Without pub, the agent stays inside its module:

agent Picker {
    on pick(items: [Int], at: Int) -> Int {
        items[at]
    }
}

The compiler refused the program:

kavach run

error: `Picker` is private to module `bots`: mark it `pub` there to use it here (spec 10.1)
src/bots.kav and 1 more file: Kavach code, then what running it prints