Hello, looks like I hit a snag in the NakedMud code base, I don't know how to diagnose a bug like this but what happened was, while in the mud itself, using the OLC editor to make a key and a door, I used the unlock command and on the door and I got this error, I was told this is a bug with the newest NakedMud codebase.
[LOG: Error running Python command, unlock:
Traceback (most recent call last): File "../lib/pymodules/cmd_manip.py", line 397, in cmd_unlock elif not has_proto(ch, ex.key, utils): NameError: global name 'has_proto' is not defined [/code]
While not being versed in python I'll leave someone to ponder this one lol, while I go back to try to fix it myself at all cost that is why I choose this forum for the help ;)
Let me explain further: each of the files in the NakedMud "pymodules" directory forms a module. To use the commands from a different module, you have to IMPORT those commands. There are two ways you can do this: first of all, you can import the module wholesale, with this:
import utils
This will import all the commands as utils.<command> such as above, utils.has_proto.
I however, like to keep my namespaces as little cluttered as possible, and only import what I need to import. That is to say, where I only need one command from another module, I will just import that command directly, like this:
from utils import has_proto
Then you would just call it like has_proto(ch, ex.key)
You can even rename commands using the FROM keyword, if you add AS. I use this for hooks a lot:
from hooks import add as add_hook from hooks import remove as remove_hook from hooks import build_info as build_hook from hooks import parse_info as parse_hook
hey thanks for the swift info as always ;) chrisd thank you utils.has_proto(ch, ex.key) I thought I should put the utils in the (ch, ex.key utils) lol and Im a bit tired today not thinking as alert as I thought, I will try this.
Let me explain further: each of the files in the NakedMud "pymodules" directory forms a module. To use the commands from a different module, you have to IMPORT those commands. There are two ways you can do this: first of all, you can import the module wholesale, with this:
import utils
This will import all the commands as utils.<command> such as above, utils.has_proto.
I however, like to keep my namespaces as little cluttered as possible, and only import what I need to import. That is to say, where I only need one command from another module, I will just import that command directly, like this:
from utils import has_proto
Then you would just call it like has_proto(ch, ex.key)
You can even rename commands using the FROM keyword, if you add AS. I use this for hooks a lot:
from hooks import add as add_hook from hooks import remove as remove_hook from hooks import build_info as build_hook from hooks import parse_info as parse_hook
Maya/Rudha
Thanks Rudha, that makes sense, a lot like #include directives
bingo! it worked, something so simple too thanks (solved)
21 Aug, 2010, David Haley wrote in the 9th comment:
Votes: 0
Quote
This will import all the commands as utils.<command> such as above, utils.has_proto.
I however, like to keep my namespaces as little cluttered as possible, and only import what I need to import. That is to say, where I only need one command from another module, I will just import that command directly, like this:
from utils import has_proto
Hrm, I also (usually) like importing the functions I need, but I wouldn't say it makes the namespace less cluttered. In fact, arguably, it adds clutter because you're adding more names to the namespace, whereas 'import utils' only adds one name to the namespace.
I tend to import the module itself when it makes things clearer; for example, 'mobile.find' can be clearer than just 'find'. Of course, the import X as Y syntax can be useful here – as you showed, something like 'from mobile import find as find_mobile' – but if you need enough things out of a given module I find it easier to just import the module.
Python imports are somewhat similar to #include directives but really there's a whole lot more to them. The process is actually remarkably complex and involves a whole bunch of checks, evaluations, etc. But sure, basically, you can think of it like #include – it makes symbols available.
You're right in a way, but when I say it makes it more cluttered, Im saying that because simply importing a module makes all its functions available. If you only need one, or a small number of them, you're loading more into memory than you need to. Granted, its a negligable amount of memory we're talking about here. For me its more a question of good design.
It -does- make sense to include the module in some cases, to aid readability. char.send() or sock.send() is going to be a little clearer than just send(). Who are you sending to?
Maya/Rudha
21 Aug, 2010, David Haley wrote in the 11th comment:
Votes: 0
Quote
You're right in a way, but when I say it makes it more cluttered, Im saying that because simply importing a module makes all its functions available. If you only need one, or a small number of them, you're loading more into memory than you need to. Granted, its a negligable amount of memory we're talking about here. For me its more a question of good design.
Actually, the whole module is loaded regardless of how many symbols you import from it. The module goes into sys.modules[<module name>]. So whether you import one or 20 symbols, the whole module gets loaded. In fact, to be precise, importing the module as its own name will cost less than importing two symbols separately, as in the former case you have a single symbol table entry for the module (plus the whole module) and in the latter case you have two symbol table entries (plus the whole module).
(If you think about it, this is almost necessarily the case, because the symbol you import could in principle refer to any other symbol in the module's symbol table. So you need the module to be available – you also need it available so that if you import the module elsewhere, you can return the copy you already loaded, instead of duplicating everything, which would be bad on several levels.)
First, if the module already exists in sys.modules (a possibility if the loader is called outside of the import machinery) then it is to use that module for initialization and not a new module. But if the module does not exist in sys.modules then it is to be added to that dict before initialization begins. If an error occurs during loading of the module and it was added to sys.modules it is to be removed from the dict.
I'm afraid that whoever explained this to you was mistaken. :sad: As I said, there really is no other way this could work, given Python's dynamic nature and the fact that a symbol in a module has access to all other symbols in that module.
So in essence what I was told about changing my code to utils. was wrong? as it did work for me and now I can use the unlock command, or was it simply a shortcut and done incorrectly, it does make sense to me as it was imported at the top of the py file, utils was not declared and yet that did work, fill me it ;)
I had no modified the code of the set modules of NakedMud, so to my surprise when I tried to unlock a door I got an error.
21 Aug, 2010, David Haley wrote in the 15th comment:
Votes: 0
The method wasn't "wrong"; I was commenting on the reasoning behind it. My exchange with Rudha here is about low-level details that you don't really need to care about at this stage in your learning. :smile:
heh hahaha, I know a little C++, just a little, but programming isn't my strong point. David, could I get a tip from you on what Free Python guide would really benefit me? I am reading the Non-Programmers Guide to Python 2.6 on wiki, is there something more hands on?
Good point, I have checked out python.org a while back when I was a little interested, but I couldn't get the code to work right due to space dependency, has that changed?
21 Aug, 2010, David Haley wrote in the 19th comment:
Votes: 0
I'm not sure what you mean by "space dependency" here…
As for a guide, well, it's hard for me to say. I came to Python after about 12 years of programming, after being rather comfortable in several languages and after college degrees. So I didn't really learn it as a new-comer; the documentation I needed was regarding subtle, Python-specific semantics, not what it means to have functions, classes, control flow, data structures, etc. Long story short, I have little personal experience with Python introductions for new programmers, so I'm afraid I can't help much there with specifics. :sad:
That said, any guide to programming can be helpful here. I need to run, unfortunately, but I would suggest looking through handouts and assignments at university courses like here or here.