In my last post on Nim, I was learning a lot about the SDL2 wrapper. In my post Nim! pt3 I had expressed that I still didn’t quite understand how TFPSmanager
was able to get imported into the example’s scope with just the statement import sdl2/gfx
. I’ve figured that bit out (because, you know, I read a little more…) and I’d like to talk about Nim’s modules briefly.
Modules in Nim are defined much like modules in Python (at least on the surface) – the folder and filename provide the module segments used with the import
statement. That’s pretty much where the comparison to Python ends.
The import
statement itself can use what I refer to as a dot-notation (import path.to.module
), or a slash-notation (import path/to/module
). The path/to/module
part is the file path, including the filename, of a.nim
file (without the .nim
portion). What is very different to Python is that, in the statement import path/to/module
, path/to/
is not part of the namespace! The “namespace” is still just module
. Therefore, as far as I can tell, the only way to resolve conflicts between module names is to use an alias.
For example:
import lib.ent.entity_manager
import lib.flush.entity_manager
entity_manager.init
Would be in conflict, but:
import lib.ent.entity_manager
import lib.flush.entity_manager as flush_emgr
entity_manager.init
flush_emgr.init
Would disambiguate the module names and resolve any conflicts.
Which leads me to my unanswered question in Nim! pt3! Nim’s modules, by default, sort of import everything from a module specified in an import
statement. Only when there is ambiguity does a module prefix need to be specified for a call to a member of the module.
If two or more modules with different names import the same member, then you can resolve the situation in a couple different ways. First, you can indeed prefix the module name onto the member call, and the other way would be to alias the member in a from
import statement (IE from lib.ent.entity_manager import init as emgr_init
).
There are a couple of other neat things that Nim does with it’s module system:
- There is an
export
statement to do “symbol forwarding” so clients of a particular module don’t have to include that modules dependancies. IE ifentity_manager
requiresentity
, and a client of theentity_manager
module would need to make use of definitions inentity
in order to use members ofentity_manager
, theentity_manager
module could have a statement likeexport entity.TEntity
to let any client that importsentity_manager
have access toTEntity
from it’s own namespace (IEentity_manager.TEntity
) import
statements can be followed by anexcept
statement, which lets clients do the inverse of what thefrom x import y
syntax let’s you do!- In order to be used outside a module, a member must be defined as being exported
Haven’t really written much useful code besides some tests for this, but I think next time I talk about Nim, I might start an actual project that I can discuss. I feel like I have a pretty good (very) basic understanding of the syntax, and I need to have some sort of project to movtivate further learning of Nim and it’s capabilities and usefulness to me.
Until next time!