Awesome
My (AppleScript-)Coding Practices
-
All lines of my code are restricted to a maximum column width of 80. I make use of continuation characters to split long lines of code over several separate lines. For me, this aids readability on a wide variety of screens, without the need to scroll horizontally. I loathe scrolling horizontally.
-
I use hard tabs of 8 character widths.
-
I use UTF16-LE text encoding.
-
I tend to favour short, mono- or dual-character variable names, which I acknowledge aren't transparent and can make interpreting their nature difficult. However, I try to be consistent with these across scripts, so that
fp
will always refer to a filepath, andL
will always refer to a list. AppleScript's tendency to homogenise variable letter case even across different scopes can make it challenging to differentiate aP
(typically referring to aprocess
in System Events) if used in the same script as ap
(which, depending on context, either refers to a prime number or an element in a parameter list). I prioritise uppercase names in these instances, whilst electing to substitute the lowercase name with an alternative. -
I utilise Script Objects a lot, even unnecessarily. Script Objects are AppleScript's watered-down imitation of what other languages refer to as a
class
. They lack many of the true features of aclass
construct, but do allow chains of inheritance to be used in similar ways. For me, however, I largely use Script Objects to organise and group blocks of code in a semantically functional way that mirrors how I might have constructed or deconstructed the coding problem in my head, making it easier for me to refactor my code if I need to, and understand what my approach was initially when I later devise an alternative method. -
Handler names, conversely to variable names, tend to be descriptive and CamelCase, often with an initial lowercase letter, but not exclusively. I favour AppleScript's labelled parameters because it provides the only means of specifying optional parameters, but I also make use of interleaved parameter labels, and also plain-and-simple parentheticals. Quite conveniently,
myFunction:param
is essentially equivalent in AppleScript tomyFunction_(param)
, which provides versatility in syntax when desired. -
I like code to look good. I'm not claiming success in this just yet, but I believe that beautiful code will ultimately end up becoming functional code. Obviously, we can all construct beautiful code that does absolutely nothing, so this isn't a law in itself, but is, in my view, a good mantra and reminder that aesthetics aid readability, solubility, and consistency.
-
A corollary of
(7)
is that I might prioritise aesthetics over adherence to any of the non-prime numbered rules stipulated here (including this one). It can also lead to syntactic inconsistency in how and where I choose to divide two similar lines of code with a continuation character that appear misplaced in one versus the other. This is rarely an oversight, but a necessary evil in order to achieve a pleasing text alignment. -
I rarely prioritise speed, but I do prioritise efficiency, and wasteful code irks me. Unnecessarily inefficient code irks me. If a piece of code will run faster if, say, a string is converted into a list of numbers before being operated on, then I will usually elect to do this. If a script object makes execution more efficient, I will elect to use one. However, if a piece of code is demonstrably quicker but also has to be a complete mess to preserve its speed, I am unlikely to care that a script runs slower if it ends up looking better. Perception is Reality.
-
I use AppleScript's
use
function to import an application's dictionary into the script, if the script is sufficiently short and primarily utilises one or two applications. This practice won't be endorsed by many, but I am good at keeping track of terminology clashes, and utilise script objects to help separate functionally-distinct aspects of a single script. I may also employ occasional use of chevron syntax if it helps avoid using atell
statement and minimises command length. A contrived example I've not actually used would be:property Finder : application "Finder" «class cfol» named "Applications" of «class sdsk» of Finder
-
In my final code reviews, I will try and perform code refactoring that hopefully makes the script more usable with minimal or zero requirement for edits if employed from within different environments, eg. Automator, Keyboard Maestro, Alfred, FastScripts, etc. This is an ongoing endeavour and not necessarily achievable in all my scripts. Some scripts may have a prefix like
KM#
in their filename, which might suggest it only works inside Keyboard Maestro. In fact, the significance of this prefix is to denote a script that operates upon Keyboard Maestro, but needn't be triggered from within Keyboard Maestro (although it would generally make the most sense to do so). -
?
-
I'm always open to suggestions on ways to do things that I might find more useful, meaningful or simply interesting. Comments, critiques, tips and questions are welcome, regardless of your own coding proficiency. I may or may not agree with an opinion or assertion at all, or at that time, or as applied to a specific situation, but no one remembers the time they met someone who agreed with everything you said, because nothing new comes from two things being the same, and it's the people who tell you that you're wrong that ensure we keep questioning ourselves and considering the other approaches that helps us to improve.
...And that's what I like to call being
AppleScriptive<sup>†</sup>
<hr>†<sub>This is irony, of course.</sub>