Canonical Names vs. Colloquial Names
Based on my experience with cfengine, one my initial design requirements for Puppet was that it support two names for every object; I have been calling these names the canonical name and the colloquial name.
For instance, take the ssh daemon. Or is that the sshd daemon? Or
the openssh daemon? Unfortunately, it depends on your operating system,
and potentially even on your environment (e.g., you could create a custom
init script that called it whatever you wanted), which is exactly the
point. We humans have a single name that we use to refer to all of these
daemons -- personally, I always think of it as "the ssh daemon", or maybe just
"sshd" -- but the computers have their own names.
The first name, the name that humans apply consistently throughout a site, I have been calling the canonical name ("canonical" because it's true everywhere), and the second name, the name that varies with every platform or whatever, I have been calling the calloquial name ("colloquial" because it's based on the local dialect, so to speak (pun intended)).
However, both of those names are, um, way too long to use as method names.
Puppet always requires a colloquial name, and it uses that as the default for
the canonical name -- that is, if you do not provide a canonical name, then
the colloquial name is used. However, the difference between the two is, um,
a touch embarrassing -- the canonical name is retrieved by calling the
name method on a Puppet type, and the canonical name is retrieved by
getting the name attribute of a Puppet type (e.g.,
name = obj[:name]).
Yes, this is hideous, and no, it's not reasonable for me to expect anyone else to understand this. But it's worse than that.
I've been planning on moving Puppet types from using the hash-style attribute
retrieval methods ([] and []=) to using standard gettor and settor
methods (e.g., name and name=). The problem is, of course, that you
would then get name clobbering -- there would be no way to distinguish the two
names.
I actually wrote up all of the code to make this change (two different ways, even) at the beginning of 2006, but this naming problem stymied me, so I left it alone (I did the work mostly on a lark, while I was travelling -- I was hoping for performance improvements, but I found them elsewhere).
Now, as I continue thinking about providers and abstraction and modeling and
those other things that keep me up at night and put the rest of you to sleep,
this problem is getting more pronounced. As I
mentioned, I'm working
on potentially adding a layer above the types to handle the @is and
@should values (or, as I've been describing it, handling the three C's --
collect, compare, commit), and changing the types so that direct method calls
work. In that case, it makes much more sense to get rid of this hash syntax.
(Yes, it must be said, Puppet was initially inspired just a bit too much by
hashes.)
So, I think I'm going to start calling the canonical name the "title", and
continue using "name" for the colloquial name. The language will continue
preferring the title over the name (you probably didn't know that it did
that), and in the majority of cases this won't matter to you. But I will have
to modify the Transportable classes to use title instead of name, and
I'll have to make a few other internal changes. Once this is done, though,
and it should be pretty straightforward, I can move to
file.uid = 0 instead of file[:uid] = 0, which I think makes more
sense; certainly it will be better for users of Puppet's library interface.
Wed, 16 Aug 2006 | Tags: puppet, design, naming