Previous Up Next

16.7  Attributed Variable Handlers

An attributed variable is a variable with some additional information which is ignored by ordinary object level system predicates. Meta level operations on attributed variables are handled by extensions which know the contents of their attributes and can specify the outcome of each operation. This mechanism is implemented using attributed variable handlers, which are user-defined predicates invoked whenever an attributed variable occurs in one of the predefined operations. The handlers are specified in the attribute declaration meta_attribute(Name, HandlerList), the second argument is a list of handlers in the form
[unify:UnifyHandler, test_unify:TUHandler, ...]
Handlers for operations which are not specified or those that are true/0 are ignored and never invoked. If Name is an existing extension, the specified handlers replace the current ones.

Whenever one of the specified operations detects an attributed variable, it will invoke all handlers that were declared for it and each of them receives either the whole attributed variable or its particular attribute as argument. The system does not check if the attribute that corresponds to a given handler is instantiated or not; this means that the handler must check itself if the attributed variable contains any attribute information or not. For instance, if an attributed variable X{a:_, b:_, c:f(a)} is unified with the attributed variable Y{a:_, b:_, c:f(b)}, the handlers for the attributes a and b should treat this as binding of two plain variables because their attributes were not involved. Only the handler for c has any work to do here. The library suspend.pl can be used as a template for writing attributed variable handlers.

The following operations invoke attributed variable handlers: The following handlers are still supported for compatibility, but their use is not recommened:

16.7.1  Printing Attributed Variables

The different output predicates treat attributed variables differently. The write/1 predicate prints the attributes using the print-handlers, while writeq/1 prints the whole attribute, so that the attributed variable can be read back. The printf/2 predicate has two options to be combined with the w format: M forces the whole attributed variable to be printed together with all its attributes in the standard format, so that it can be read back in. With the m option the attributed variable is printed using the handlers defined for the print operation. If there is only one handled attribute, the attributed variable is printed as
X{Attr}
where Attr is the value obtained from the handler. If there are several handled attributes, all attributes are qualified like in
X{a:A, b:B, c:C}.
An attributed variable X{m:a} with print handler =/2 can thus be printed in different ways, e.g.: 1
printf("%w", [X{m:a}])   or write(X{m:a}):    X   
printf("%vMw", [X{m:a}]) or writeq(X{m:a}):   _g246{suspend : _g242, m : a}
printf("%mw", [X{m:a}]):                      X{a}
printf("%Mw", [X{m:a}]):                      X{suspend : _g251, m : a}
printf("%Vmw", [X{m:a}]):                     X_g252{a}
Write macros for attributed variables are not allowed because one extension alone should not decide whether the other attributes will be printed or not.


Previous Up Next