\chapter{Class Variables} \label{sec:classvar} Class variables act as read-only storage for class-constants. They are normally used for storing setting information, such as fonts, colours etc. For this reason, the default value for a \class{class_variable} is defined with the declaration of it, but this default my be overruled using the \file{Defaults} file. The system defaults file is located in the \product{} home directory (`@pce <-home'). This file contains an \jargon{include} statement, including the file \file{~/.xpce/Defaults},% \footnote{On Windows systems, \file{~} expands to \file{\%HOME\%}, \file{\%USERPROFILE\%}, \file{\%HOMEDRIVE\%/\%HOMEPATH\%} or the root of the current drive. See expand_file_name/2 of the SWI-Prolog manual.} which may be used by the developer and application user to specify defaults. Many \product{} built-in classes define class-variables. These can be examined using the \tool{ClassBrowser} (see \secref{classbrowser}) from the online manual tools. \section{Accessing Class Variables} \label{sec:classvaraccess} Class variables define \jargon{get-}behaviour and can be accessed using the normal get/[3-13] call. Class variables are the last type of behaviour checked when resolving a get-method. Below are the most commonly used methods to access class-variables. \begin{description} \getmethod{object}{class_variable_value}{name}{any} Return the value of the named class-variable. Fails silently if the class does not define the given class-variable. \getmethod{class}{class_variable}{name}{class_variable} Return the \class{class_variable} object with the given name. Fails silently if the class does not define the given class-variable. \bothmethod{class_variable}{value}{any} Reads or writes the class-variable value. The argument is type-checked using `class_variable<-type' if the value is written. Writing class-variables should be handled with care, as existing instances of the class are not notified of the change, and may not be prepared deal with changes of the class-variable value. pce_image_directory/1 is an example of a predicate modifying the image.path class-variable. \end{description} \section{Class variable and instance variables} Class-variables may be used as defaults for instance-variables that can be modified through the \file{Defaults} file. For example, class \class{text} defines both the instance- and class-variable {\em font}. The class-variable defines the default font, while the font can be modified explicitely at instance-initialisation, or using the ->font method afterwards. If a class defines both an instance- and a class-variable with the same name, object-allocation will use the \class{constant} @class_default for the initial value of the slot. First access will replace this value using the value from the class-variable. Instance-variables supercede class-variables for \jargon{get-}behaviour. To access the class-variable explicitly, use the methods from \secref{classvaraccess}. \section{The `Defaults' file} The \file{Defaults} file consists of statements. Each statement is on a separate line. A statement may be split over several lines by preceeding the newline with a backslash (\verb$\$). The exclamation mark (\const{!}) is the line-comment character. All input from the \const{!} upto the following newline is replaced by a single space-character. Empty lines or lines containing only blank space are ignored. Default files may include other default files using the statement \begin{quote} {\tt \#include} \end{quote} Default statements are of the form: \begin{quote} .: \end{quote} Where denotes the name of the class, or \const{*} to indicate the default applies for any class defining this class-variable. If both forms are found, the statement with the explicit class-name is used. denotes the class-variable name. is the default value of the class-variable. The syntax for is similar to the arguments of send/[2-12]. The (informal) syntax for is below. \def\isa{} \def\ora{} \renewcommand{\isa}{& ::= &} \renewcommand{\ora}{& $\mid$ &} \begin{quote} \begin{tabular}{|lrl|} \hline \isa \\ \ora \\ \ora \\ \ora @ \\ \ora \\ \ora \\ \hline \isa {\tt [} \{, \} {\tt ]} \\ \ora {\tt [} {} {\tt ]} \\ \hline \isa {\tt ()} \\ \ora {\tt (} \{, \} {\tt )} \\ \ora \\ \ora \\ \ora \\ \ora {\tt "} {\tt "} \\ \hline \isa \{$|${\tt ""}\} \\ \hline \isa \{$|$\} \\ \ora {\tt '} \{$|${\tt ''}\} {\tt '} \\ \hline \end{tabular} \end{quote} \section{Class variables in User Defined Classes} Class-variables are declared, similar to instance-variables. through macro-expansion inside the :- pce_begin_class/[2,3] \ldots :- pce_end_class/0 definition of a class. The syntax is: \begin{quote} {\tt class_variable(}{\tt ,} {\tt ,} {\tt ,} []{\tt )}. \end{quote} defines the value if not overruled in the \file{Defaults} file. It is a Prolog term describing an object similar to the arguments of send/[2-12]. In the following example. there is a class with the property `expert_level'. The program defines the default level to be novice. The user may change that in his/her personal \file{Defaults} file or change it while the application is running. As the value may change at runtime, there should be an instance- as well as a class-variable. Below is the skeleton for this code: \begin{code} variable(expert_level, {novice,advanced,expert}, get, "Experience level of the user"). class_variable(expert_level, @default, novice). expert_level(Obj, Level:{novice,advanced,expert}) :-> send(Obj, slot, expert_level, Level), . ..., ( get(Obj, expert_level, expert) -> ... ; ... ), ... \end{code} \mbox{}