maybe
in the return type expresses the fact that the function might return undefined rather than an attribute (in the absence of the right kind of processes and windows at run-time).
The AppleScript version is using error handling, while the JavaScript version is using conditional assignment - some languages formalise support for using the type system
but you can always do it manually, returning something like undefined
, or null
, when the input to a function is invalid (or, to put it another way, no output is defined for a given input).
Generally, the appeal of avoiding error handling is that the latter tends to disrupt the composition of functions. If a deeply nested function gets an out of range input and trips an error, the outer functions will choke. Option types provide a way of handling such cases without abandoning compositional patterns of structuring.
A more general (reusable) approach to attribute reading here might, incidentally, be:
(function () {
'use strict';
// maybeFrontWinAttributes :: () -> Maybe attributes
function maybeFrontWinAttributes() {
var procs = Application('System Events')
.applicationProcesses
.whose({
frontmost: true
}),
// Frontmost standard window ?
proc = procs.length ? procs.at(0) : undefined,
lstWins = proc ? proc.windows
.whose({
subrole: 'AXStandardWindow'
}) : [];
return lstWins.length ? lstWins[0]
.attributes : undefined;
}
var mbAttribs = maybeFrontWinAttributes();
if (mbAttribs) {
var fullScreen = mbAttribs.byName('AXFullScreen');
fullScreen.value = !fullScreen.value();
}
})();
Given that there are some other useful attributes in the full set:
return Object.keys(mbAttribs)
.map(function (k) {
return mbAttribs[k].name();
})
–>
["AXFocused", "AXFullScreen", "AXTitle",
"AXPosition", "AXGrowArea", "AXMinimizeButton",
"AXDocument", "AXSections", "AXCloseButton",
"AXMain", "AXFullScreenButton", "AXProxy",
"AXDefaultButton", "AXMinimized", "AXChildren",
"AXRole", "AXParent", "AXTitleUIElement",
"AXCancelButton", "AXModal", "AXSubrole",
"AXZoomButton", "AXRoleDescription", "AXSize",
"AXToolbarButton", "AXFrame", "AXIdentifier"]