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.
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
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.
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
exportstatement to do “symbol forwarding” so clients of a particular module don’t have to include that modules dependancies. IE if
entity, and a client of the
entity_managermodule would need to make use of definitions in
entityin order to use members of
entity_managermodule could have a statement like
export entity.TEntityto let any client that imports
entity_managerhave access to
TEntityfrom it’s own namespace (IE
importstatements can be followed by an
exceptstatement, which lets clients do the inverse of what the
from x import ysyntax 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!