Did you know ... | Search Documentation: |
Pack with -- README.md |
?- use_module(library(with)). % IO streams automatically closed ?- with(open('/tmp/foo.txt', write, Stream), format(Stream, 'My context was managed!', [])). % Asserted clauses automatically retracted. ?- dynamic(foo/1), with(assertz(foo(1) :- true), (foo(X), writeln(X))), foo(Y), writeln(Y). 1 false. % Changed setting automatically reverted ?- [user]. :- setting(mymod:foo, boolean, true, ''). |: true. with(setting(mymod:foo, false), setting(mymod:foo, V)), setting(mymod:foo, V1). V = false, V1 = true. % Automatically revert changes to environment ?- with(setenv('FOO', 'BAR'), (getenv('FOO', V), writeln(V))), getenv('FOO', V), writeln(V). BAR false. % And you can define your own! ?- [user]. with:manage_context(my_ctx(X), assert(foo(X)), retract(foo(X))). |: true. ?- with(my_ctx(1), listing(foo)), listing(foo). :- dynamic foo/1. foo(1). :- dynamic foo/1. true
This module provides context management for various types of Prolog
objects. Builtin support includes IO Streams, environment variables,
dynamic clauses, prolog flags, library(setting)
, and
library(debug). User defined contexts can be implemented using the
multifile predicate manage_context/3. manage_context(Term, Setup,
Cleanup)
defines a setup/cleanup pair for a specific type of
term. `with(Term, Goal)
` calls Goal
using setup_call_cleanup/3,
with the corresponding setup and cleanup goals. If List is a list of
terms then, `with(List, Goal)
` nests the corresponding context
managers.
There is one difference between the semantics of setup_call_cleanup/3
and the corresponding goal using this library. Setup
and Cleanup
goals must succeed. If they fail, the error
`error(mode_error(must_succeed, FailingGoal))
` is thrown.
For example, the provided manage_context/3 clause for opening files could be defined:
with:manage_context(open(File, Mode, Stream), open(File, Mode, Stream), close(Stream)).
The result is that the following are equivalent:
?- setup_call_cleanup(open(File, read, Stream), is_stream(Stream), close(Stream)). ?- use_module(library(with)), with(open(File, read, Stream), is_stream(Stream)).
To show defined context managers, using `listing/1
`. E.g, the
context managers packaged with this module are:
?- use_module(library(with)), listing(with:manage_context/3). manage_context(open(A, C, D), (absolute_file_name(A, B), open(B, C, D)), close(D)). manage_context(assertz(A), assertz(A, B), erase(B)). manage_context(setting(A, B), (setting(A, C), set_setting(A, B)), set_setting(A, C)).
Using SWI-Prolog 6.3 or later:
?- pack_install(with).
Author: Eyal Dechter