Utilização de módulos em cristal
Conforme sua aplicação cresce, você gostaria de passar de um grande arquivo .cr para separar seu código em arquivos menores.
Você pode usar o requerimento do seu arquivo .cr principal para adicionar código de outros arquivos:
requerem "./ferramentas/*".
Esta declaração adicionará o código do diretório de ferramentas, relativo ao seu arquivo .cr principal.
Isso ajudará a separar sua aplicação "fisicamente", mas também pode ser desejável separá-la logicamente - talvez parte do código possa ser reutilizado em outros projetos, e talvez você também queira evitar colisões de namespace.
O que é uma colisão de namespace?
Se um método ou nome de classe, ou nome constante for usado duas vezes em arquivos de origem diferentes no namespace global, você terá uma colisão.
Como é que o compilador deve saber, que método/classe quer realmente dos dois que estão definidos?
Para evitar colisões de namespace você separa seu código em módulos.
por exemplo:
módulo Debug
classe Classe de Amostra
final
SAMPLE_CONSTANT = "algum valor".
macro samplemacro(some_variable)
#algum código macro
final
1TP3O seu código vai para aqui
final
Código de acesso em módulos
Agora você pode acessar o código (depois de ter requerido o arquivo em que o módulo está definido) desta forma:
sampleinstance = Debug::SampleClass.new()
p Debug::SAMPLE_CONSTANT
Debug.samplemacro
Note que uma macro é chamada com uma sintaxe ".", não com uma sintaxe ":". Você pode considerá-la como um método do Módulo.
Incluindo módulos
Se, por outro lado, você achar a notação adicional cansativa, você pode incluir o módulo usando o nome do método assim:
incluem Debug
então você poderá acessar os métodos, classes, constantes e macros sem qualquer notação adicional - como se o código fosse literalmente copiado e colado em seu outro arquivo fonte:
sampleinstance = SampleClass.new()
p SAMPLE_CONSTANT
samplemacro