Memisahkan Modul ke File yang Berbeda

Sejauh ini, semua contoh dalam bab ini telah mendefinisikan beberapa modul dalam satu file. Ketika modul menjadi besar, Anda mungkin ingin memindahkan definisi mereka ke file terpisah untuk memudahkan navigasi kode.

For example, let’s start from the code in Listing 7-7 that had multiple restaurant modules. We’ll extract modules into files instead of having all the modules defined in the crate root file. In this case, the crate root file is src/lib.cairo.

First, we’ll extract the front_of_house module to its own file. Remove the code inside the curly brackets for the front_of_house module, leaving only the mod front_of_house; declaration, so that src/lib.cairo contains the code shown in Listing 7-14. Note that this won’t compile until we create the src/front_of_house.cairo file.

Filename: src/lib.cairo

mod front_of_house;

use crate::front_of_house::hosting;

fn eat_at_restaurant() {
    hosting::add_to_waitlist();
}

Listing 7-14: Declaring the front_of_house module whose body will be in src/front_of_house.cairo

Next, place the code that was in the curly brackets into a new file named src/front_of_house.cairo, as shown in Listing 7-15. The compiler knows to look in this file because it came across the module declaration in the crate root with the name front_of_house.

Filename: src/front_of_house.cairo

pub mod hosting {
    pub fn add_to_waitlist() {}
}

Listing 7-15: Definitions inside the front_of_house module in src/front_of_house.cairo

Note that you only need to load a file using a mod declaration once in your module tree. Once the compiler knows the file is part of the project (and knows where in the module tree the code resides because of where you’ve put the mod statement), other files in your project should refer to the loaded file’s code using a path to where it was declared, as covered in the "Paths for Referring to an Item in the Module Tree" chapter. In other words, mod is not an “include” operation that you may have seen in other programming languages.

Selanjutnya, kita akan mengekstrak modul hosting ke dalam file terpisah. Proses ini agak berbeda karena hosting adalah modul anak dari front_of_house, bukan dari modul akar. Kita akan menempatkan file untuk hosting dalam direktori baru yang akan dinamai sesuai dengan leluhurnya dalam pohon modul, dalam hal ini src/front_of_house/.

Untuk memulai proses memindahkan hosting, kita mengubah src/front_of_house.cairo sehingga hanya berisi deklarasi modul hosting:

Filename: src/front_of_house.cairo

pub mod hosting;

Kemudian, kita membuat direktori src/front_of_house dan sebuah file hosting.cairo untuk berisi definisi yang dibuat di dalam modul hosting:

Filename: src/front_of_house/hosting.cairo

pub fn add_to_waitlist() {}

Jika kita memindahkan hosting.cairo ke dalam direktori src, kompiler akan mengharapkan kode hosting.cairo berada dalam modul hosting yang dideklarasikan di akar krate, dan bukan dideklarasikan sebagai anak modul dari modul front_of_house. Aturan kompiler untuk mengecek file mana yang harus diperiksa untuk kode modul mana membuat direktori dan file lebih sesuai dengan pohon modul.

Kami telah memindahkan kode setiap modul ke file terpisah, dan pohon modul tetap sama. Panggilan fungsi dalam eat_at_restaurant akan berfungsi tanpa modifikasi apa pun, meskipun definisinya berada di file yang berbeda. Teknik ini memungkinkan Anda memindahkan modul ke file baru ketika ukurannya berkembang.

Note that the use crate::front_of_house::hosting; statement in src/lib.cairo also hasn’t changed, nor does use have any impact on what files are compiled as part of the crate. The mod keyword declares modules, and Cairo looks in a file with the same name as the module for the code that goes into that module.

Ringkasan

Cairo lets you split a package into multiple crates and a crate into modules so you can refer to items defined in one module from another module. You can do this by specifying absolute or relative paths. These paths can be brought into scope with a use statement so you can use a shorter path for multiple uses of the item in that scope. Module code is private by default.