Config::XrmDatabase This is a pure Perl implementation of the X Window Resource Manager Database (XrmDB). It allows creation and manipulation of Xrm compliant databases. Warning! The XrmDB refers to names and resources. These days they are more typically called keys and values. The terminology used below (and sometimes in the names of subroutines and methods) mixes these two approaches, sometimes a bit too liberally. The XrmDB differs from typical key-value stores in that a stored key may be only partially specified, so that a single entry can provide the value for many different queries. Keys A key is a sequence of *components* (such as "editor", "toolbar", and "foreground") separated by *bindings*. A binding says how the components on either side of it are related: "." The next component must follow immediately. "editor.foreground" matches only "editor.foreground". "*" Any number of components, *including none*, may come between. "editor*foreground" matches "editor.foreground", "editor.toolbar.foreground", "editor.toolbar.save.foreground", and so on. A key which begins with "*" may match starting at any level: *foreground matches "foreground", "toolbar.foreground", and "editor.toolbar.save.foreground". A key which doesn't begin with a binding must match starting at the first level. Separately from bindings, a component may be the placeholder "?", which stands for exactly one component, whatever it is. "editor.?.foreground" matches "editor.toolbar.foreground" and "editor.menu.foreground", but not "editor.foreground" or "editor.toolbar.save.foreground". "?" and "*" are easily confused. "?" *is* a component, and always takes the place of exactly one level. "*" is a binding; it sits *between* components and can span any number of levels, including none. The last component of a key must be a name or class component; a key may not end in "?" or in a binding. A key containing neither "?" nor "*" is *fully qualified*. (N.B., the X Window System documentation calls "." a *tight* binding and "*" a *loose* binding.) Names and classes Each key that is queried has a *class*, a parallel key with the same number of components. Classes provide a second way of addressing a key: a stored key may refer to a level by the name's component or by the class's component. A class essentially creates a namespace, so that values can be assigned based on which namespace a key belongs to rather than on the content of the key. Let's say that you have a number of keys that end in "Foreground": a.b.c.Foreground d.e.f.Foreground x.y.z.Foreground and you want to set a value for any keys which end in "Foreground": *Foreground : 'yellow' To give each one its own value: a.b.c.Foreground : 'red' d.e.f.Foreground : 'blue' x.y.z.Foreground : 'green' Let's say that "a.b.c.Foreground" and "d.e.f.Foreground" are in the same class, "U.V.W.Foreground", and all keys in that class should have the same value: U.V.W.Foreground : 'red' x.y.z.Foreground : 'green' At some point, a new hierarchy of keys that begin with "g" is added to that class, but they should have a different value: g.V.W.Foreground : 'magenta' You could try this: g.?.?.Foreground : 'magenta' But that would affect *all* keys that begin with "g", not just those in that class. Classes help bring some order, but this system can become very confusing if some discipline isn't maintained. Matching "query" is given a fully qualified name and its fully qualified class, which must have the same number of components. They are compared with the stored keys one level at a time, from left to right. A stored key's component matches a level if it is the name's component, the class's component, or "?"; alternatively, a "*" in the stored key may span the level. More than one stored key may match a query. When that happens, precedence rules choose the one whose value is returned. Precedence at a single level Consider a query for the name "editor.toolbar.save.foreground" with the class "Editor.Box.Button.Foreground". Each of the following keys matches it. They differ only in how they match the third level (name "save", class "Button"), and are listed from highest to lowest precedence: 1. The name, immediately following the previous level editor.toolbar.save.foreground 2. The name, following a "*" which spans no components editor.toolbar*save.foreground 3. The class, immediately following the previous level editor.toolbar.Button.foreground 4. The class, following a "*" which spans no components editor.toolbar*Button.foreground 5. "?", immediately following the previous level editor.toolbar.?.foreground 6. "?", following a "*" which spans no components editor.toolbar*?.foreground 7. The level is spanned by a "*", so the key has no component there editor.toolbar*foreground In other words: * Any component that matches the level (name, class, or "?") beats spanning the level with a "*". * A name beats a class, and a class beats "?", regardless of the binding which precedes them. * Between two otherwise equal matches, a component which immediately follows the previous level (".") beats one which follows a "*". Note that a "*" which spans no components does not cause a level to be skipped. In rules 2, 4, and 6, the key still has a component at the third level, and it is that component which is compared. Precedence across levels Levels are compared from left to right, and the first level at which two keys differ decides between them; later levels matter only if all earlier ones are the same. For example, using the same query of name "editor.toolbar.save.foreground" with class "Editor.Box.Button.Foreground": editor*save.foreground editor.toolbar.?.foreground the second key wins. At the second level it matches "toolbar" by name (rule 1), while the first key spans that level with a "*" (rule 7). That the first key matches "save" by name at the third level, while the second key only matches it with "?", doesn't matter. Similarly, of Editor.toolbar.save.foreground editor*foreground the second key wins, even though the first is much more specific. At the first level, "editor" matches by name (rule 1), while "Editor" only matches by class (rule 3). INSTALLATION This is a Perl module distribution. It should be installed with whichever tool you use to manage your installation of Perl, e.g. any of cpanm . cpan . cpanp -i . Consult http://www.cpan.org/modules/INSTALL.html for further instruction. Should you wish to install this module manually, the procedure is perl Build.PL ./Build ./Build test ./Build install COPYRIGHT AND LICENSE This software is Copyright (c) 2021 by Smithsonian Astrophysical Observatory. This is free software, licensed under: The GNU General Public License, Version 3, June 2007