Path: | intro.txt |
Last Update: | Mon May 29 14:43:11 PDT 2006 |
The Preferences class is an easy way to make variables in an application persist in a file. The file is human readable, through the magic of YAML. Preferences vary from user to user, so typically the file used for persistence will be chosen based on the user’s environment as well as the name of the app. Any pair of methods that look like a reader/writer pair can be persisted, so existing variables can be stored with little additional fuss and bother.
require 'preferences' PREFS = Preferences.new("/tmp/prefs") class Window attr_accessor :x, :y, :z def initialize PREFS.register "my app/window" do |entry| entry.var "x", "y" => "default_y" entry.var "z" end end def run @x = 7 # emulate user's interaction end end Window.new.run PREFS.save
After executing this code, /tmp/prefs contains:
my app: window: x: 7 y: default_y z:
When the program is run again, these saved preferences will be loaded into the variables when the PREFS.register method is called.
Each object with persistent variables registers (typically in its initialize method) to have its variables stored in the file. The structure of the preferences file is nested hashes. Each object registers to have its data stored in a hash nested at a certain key in this structure. The key is usually a path string of the form "key1/key2/…". The components of this string are used in sequence to access the nested hash which stores the data for the object. For example, examples/foursplit-prefs.rb generates the following preferences file:
--- main window: x: 200 y: 100 splitter: hSplit: 1219 expanded: -1 subsplitter: hSplit: 1641 expanded: -1 vSplit: 2307 vSplit: 1491 height: 600 width: 800
The key "main window/splitter/subsplitter" accesses the hash of persistent values of variables belonging to the subsplitter. This hash specifies values for the three variables, vSplit hSplit and expanded.
Note that there are two kinds of keys involved: keys like "splitter", which define a path through the nesting of hashes, and keys like "x", which specify variables. The former are branching nodes and the latter are leaf nodes in the preferences tree. An optional convention is to use Strings for the former and Symbols for the latter, but this is not necessary and can make the file a little harder to read.
When you call Preferences#register, the key does not have to be a literal string, but can of course be different with each call to initialize. This allows different instances of the same class (distinguished perhaps by their arguments or order of creation) to have distinct persistent data.
Each object can register only one key for a particular preferences file. However, two or more objects may register the same key.
Registering variables does not define them in the program. They must already exist, either defined by means of attr_accessor or defined as methods. Registering existing methods can be very useful with a library like FXRuby. The foursplit-prefs.rb example shows how to apply Preferences to a FXRuby app.
When registering a variable, the object may also register a default value for it.
A class may have its own persistent preferences. See examples/class-prefs.rb.
The preferences dir should depend on the user, on the app, and on the platform. The Preferences class provides a convenience method, Preferences.dir, to select a suitable user-specific and platform-specific dir in which the app can create its app-specific dir and/or file.
Preferences uses two undocumented methods, read_pref_file and write_pref_file, to save and restore preferences from a file. The default implementations use FileUtils.mkdir_p, File.open, YAML.dump, and YAML.load. However, an alternate implementation might use the Windows registry, or a database. Simply subclass Preferences and implement these two methods as desired.
The Preferences class makes no effort to reconcile the preferences written with the file as it exists on disk. If the file on disk has changed between the time preferences were loaded and the time preferences were saved, those changes will be lost.
Usable under the Ruby license. Copyright (C)2004-2006 Joel VanderWerf. Questions to vjoel@users.sourceforge.net.