/usr/lib/swi-prolog/doc/Manual/exception.html is in swi-prolog-nox 6.6.4-2ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>SWI-Prolog 7.1.10 Reference Manual: Section 4.10</title><link rel="home" href="index.html">
<link rel="contents" href="Contents.html">
<link rel="index" href="DocIndex.html">
<link rel="summary" href="summary.html">
<link rel="previous" href="metacall.html">
<link rel="next" href="signal.html">
<style type="text/css">
/* Style sheet for SWI-Prolog latex2html
*/
dd.defbody
{ margin-bottom: 1em;
}
dt.pubdef, dt.multidef
{ color: #fff;
padding: 2px 10px 0px 10px;
margin-bottom: 5px;
font-size: 18px;
vertical-align: middle;
overflow: hidden;
}
dt.pubdef { background-color: #0c3d6e; }
dt.multidef { background-color: #ef9439; }
.bib dd
{ margin-bottom: 1em;
}
.bib dt
{ float: left;
margin-right: 1.3ex;
}
pre.code
{ margin-left: 1.5em;
margin-right: 1.5em;
border: 1px dotted;
padding-top: 5px;
padding-left: 5px;
padding-bottom: 5px;
background-color: #f8f8f8;
}
div.navigate
{ text-align: center;
background-color: #f0f0f0;
border: 1px dotted;
padding: 5px;
}
div.title
{ text-align: center;
padding-bottom: 1em;
font-size: 200%;
font-weight: bold;
}
div.author
{ text-align: center;
font-style: italic;
}
div.abstract
{ margin-top: 2em;
background-color: #f0f0f0;
border: 1px dotted;
padding: 5px;
margin-left: 10%; margin-right:10%;
}
div.abstract-title
{ text-align: center;
padding: 5px;
font-size: 120%;
font-weight: bold;
}
div.toc-h1
{ font-size: 200%;
font-weight: bold;
}
div.toc-h2
{ font-size: 120%;
font-weight: bold;
margin-left: 2em;
}
div.toc-h3
{ font-size: 100%;
font-weight: bold;
margin-left: 4em;
}
div.toc-h4
{ font-size: 100%;
margin-left: 6em;
}
span.sec-nr
{
}
span.sec-title
{
}
span.pred-ext
{ font-weight: bold;
}
span.pred-tag
{ float: right;
padding-top: 0.2em;
font-size: 80%;
font-style: italic;
color: #fff;
}
div.caption
{ width: 80%;
margin: auto;
text-align:center;
}
/* Footnotes */
.fn {
color: red;
font-size: 70%;
}
.fn-text, .fnp {
position: absolute;
top: auto;
left: 10%;
border: 1px solid #000;
box-shadow: 5px 5px 5px #888;
display: none;
background: #fff;
color: #000;
margin-top: 25px;
padding: 8px 12px;
font-size: larger;
}
sup:hover span.fn-text
{ display: block;
}
/* Lists */
dl.latex
{ margin-top: 1ex;
margin-bottom: 0.5ex;
}
dl.latex dl.latex dd.defbody
{ margin-bottom: 0.5ex;
}
/* PlDoc Tags */
dl.tags
{ font-size: 90%;
margin-left: 5ex;
margin-top: 1ex;
margin-bottom: 0.5ex;
}
dl.tags dt
{ margin-left: 0pt;
font-weight: bold;
}
dl.tags dd
{ margin-left: 3ex;
}
td.param
{ font-style: italic;
font-weight: bold;
}
/* Index */
dt.index-sep
{ font-weight: bold;
font-size: +1;
margin-top: 1ex;
}
/* Tables */
table.center
{ margin: auto;
}
table.latex
{ border-collapse:collapse;
}
table.latex tr
{ vertical-align: text-top;
}
table.latex td,th
{ padding: 2px 1em;
}
table.latex tr.hline td,th
{ border-top: 1px solid black;
}
table.frame-box
{ border: 2px solid black;
}
</style>
</head>
<body style="background:white">
<div class="navigate"><a class="nav" href="index.html"><img src="home.gif" alt="Home"></a>
<a class="nav" href="Contents.html"><img src="index.gif" alt="Contents"></a>
<a class="nav" href="DocIndex.html"><img src="yellow_pages.gif" alt="Index"></a>
<a class="nav" href="summary.html"><img src="info.gif" alt="Summary"></a>
<a class="nav" href="metacall.html"><img src="prev.gif" alt="Previous"></a>
<a class="nav" href="signal.html"><img src="next.gif" alt="Next"></a>
</div>
<h2 id="sec:exception"><a id="sec:4.10"><span class="sec-nr">4.10</span> <span class="sec-title">ISO
compliant Exception handling</span></a></h2>
<a id="sec:exception"></a>
<p>SWI-Prolog defines the predicates <a id="idx:catch3:609"></a><a class="pred" href="exception.html#catch/3">catch/3</a>
and <a id="idx:throw1:610"></a><a class="pred" href="exception.html#throw/1">throw/1</a>
for ISO compliant raising and catching of exceptions. In the current
implementation (as of 4.0.6), most of the built-in predicates generate
exceptions, but some obscure predicates merely print a message, start
the debugger and fail, which was the normal behaviour before the
introduction of exceptions.
<dl class="latex">
<dt class="pubdef"><span class="pred-tag">[ISO]</span><a id="catch/3"><strong>catch</strong>(<var>:Goal,
+Catcher, :Recover</var>)</a></dt>
<dd class="defbody">
Behaves as <a id="idx:call1:611"></a><a class="pred" href="metacall.html#call/1">call/1</a>
if no exception is raised when executing <var>Goal</var>. If an
exception is raised using <a id="idx:throw1:612"></a><a class="pred" href="exception.html#throw/1">throw/1</a>
while <var>Goal</var> executes, and the <var>Goal</var> is the innermost
goal for which <var>Catcher</var> unifies with the argument of <a id="idx:throw1:613"></a><a class="pred" href="exception.html#throw/1">throw/1</a>,
all choice points generated by <var>Goal</var> are cut, the system
backtracks to the start of <a id="idx:catch3:614"></a><a class="pred" href="exception.html#catch/3">catch/3</a>
while preserving the thrown exception term, and <var>Recover</var> is
called as in <a id="idx:call1:615"></a><a class="pred" href="metacall.html#call/1">call/1</a>.
<p>The overhead of calling a goal through <a id="idx:catch3:616"></a><a class="pred" href="exception.html#catch/3">catch/3</a>
is comparable to
<a id="idx:call1:617"></a><a class="pred" href="metacall.html#call/1">call/1</a>.
Recovery from an exception is much slower, especially if the exception
term is large due to the copying thereof.</dd>
<dt class="pubdef"><span class="pred-tag">[ISO]</span><a id="throw/1"><strong>throw</strong>(<var>+Exception</var>)</a></dt>
<dd class="defbody">
Raise an exception. The system looks for the innermost <a id="idx:catch3:618"></a><a class="pred" href="exception.html#catch/3">catch/3</a>
ancestor for which <var>Exception</var> unifies with the <var>Catcher</var>
argument of the <a id="idx:catch3:619"></a><a class="pred" href="exception.html#catch/3">catch/3</a>
call. See <a id="idx:catch3:620"></a><a class="pred" href="exception.html#catch/3">catch/3</a>
for details.
<p>ISO demands that <a id="idx:throw1:621"></a><a class="pred" href="exception.html#throw/1">throw/1</a>
make a copy of <var>Exception</var>, walk up the stack to a <a id="idx:catch3:622"></a><a class="pred" href="exception.html#catch/3">catch/3</a>
call, backtrack and try to unify the copy of
<var>Exception</var> with <var>Catcher</var>. SWI-Prolog delays making a
copy of
<var>Exception</var> and backtracking until it actually finds a matching
<a id="idx:catch3:623"></a><a class="pred" href="exception.html#catch/3">catch/3</a>
goal. The advantage is that we can start the debugger at the first
possible location while preserving the entire exception context if there
is no matching <a id="idx:catch3:624"></a><a class="pred" href="exception.html#catch/3">catch/3</a>
goal. This approach can lead to different behaviour if <var>Goal</var>
and <var>Catcher</var> of <a id="idx:catch3:625"></a><a class="pred" href="exception.html#catch/3">catch/3</a>
call shared variables. We assume this to be highly unlikely and could
not think of a scenario where this is useful.<sup class="fn">50<span class="fn-text">I'd
like to acknowledge Bart Demoen for his clarifications on these matters.</span></sup>
<p>If an exception is raised in a call-back from C (see <a class="sec" href="foreign.html">chapter
9</a>) and not caught in the same call-back, <a class="func" href="foreigninclude.html#PL_next_solution()">PL_next_solution()</a>
fails and the exception context can be retrieved using <a class="func" href="foreigninclude.html#PL_exception()">PL_exception()</a>.
</dd>
</dl>
<p><h3 id="sec:debugexceptions"><a id="sec:4.10.1"><span class="sec-nr">4.10.1</span> <span class="sec-title">Debugging
and exceptions</span></a></h3>
<a id="sec:debugexceptions"></a>
<p><a id="idx:exceptionsdebugging:626"></a><a id="idx:debuggingexceptions:627"></a>Before
the introduction of exceptions in SWI-Prolog a runtime error was handled
by printing an error message, after which the predicate failed. If the
Prolog flag <a class="flag" href="flags.html#flag:debug_on_error">debug_on_error</a>
was in effect (default), the tracer was switched on. The combination of
the error message and trace information is generally sufficient to
locate the error.
<p>With exception handling, things are different. A programmer may wish
to trap an exception using <a id="idx:catch3:628"></a><a class="pred" href="exception.html#catch/3">catch/3</a>
to avoid it reaching the user. If the exception is not handled by user
code, the interactive top level will trap it to prevent termination.
<p>If we do not take special precautions, the context information
associated with an unexpected exception (i.e., a programming error) is
lost. Therefore, if an exception is raised which is not caught using
<a id="idx:catch3:629"></a><a class="pred" href="exception.html#catch/3">catch/3</a>
and the top level is running, the error will be printed, and the system
will enter trace mode.
<p>If the system is in a non-interactive call-back from foreign code and
there is no <a id="idx:catch3:630"></a><a class="pred" href="exception.html#catch/3">catch/3</a>
active in the current context, it cannot determine whether or not the
exception will be caught by the external routine calling Prolog. It will
then base its behaviour on the Prolog flag
<a class="flag" href="flags.html#flag:debug_on_error">debug_on_error</a>:
<p>
<ul class="latex">
<li><i>current_prolog_flag(debug_on_error, false)</i><br>
The exception does not trap the debugger and is returned to the foreign
routine calling Prolog, where it can be accessed using <a class="func" href="foreigninclude.html#PL_exception()">PL_exception()</a>.
This is the default.
<li><i>current_prolog_flag(debug_on_error, true)</i><br>
If the exception is not caught by Prolog in the current context, it will
trap the tracer to help analyse the context of the error.
</ul>
<p>While looking for the context in which an exception takes place, it
is advised to switch on debug mode using the predicate <a id="idx:debug0:631"></a><a class="pred" href="debugger.html#debug/0">debug/0</a>.
The hook
<a id="idx:prologexceptionhook4:632"></a><a class="pred" href="excepthook.html#prolog_exception_hook/4">prolog_exception_hook/4</a>
can be used to add more debugging facilities to exceptions. An example
is the library <code>library(http/http_error)</code>, generating a full
stack trace on errors in the HTTP server library.
<p><h3 id="sec:exceptterm"><a id="sec:4.10.2"><span class="sec-nr">4.10.2</span> <span class="sec-title">The
exception term</span></a></h3>
<a id="sec:exceptterm"></a>
<p>Built-in predicates generate exceptions using a term
<code>error(Formal, Context)</code>. The first argument is the `formal'
description of the error, specifying the class and generic defined
context information. When applicable, the ISO error term definition is
used. The second part describes some additional context to help the
programmer while debugging. In its most generic form this is a term of
the form <code>context(Name/Arity, Message)</code>, where
<var>Name</var>/<var>Arity</var> describes the built-in predicate that
raised the error, and <var>Message</var> provides an additional
description of the error. Any part of this structure may be a variable
if no information was present.
<p><h3 id="sec:printmsg"><a id="sec:4.10.3"><span class="sec-nr">4.10.3</span> <span class="sec-title">Printing
messages</span></a></h3>
<a id="sec:printmsg"></a>
<p>The predicate <a id="idx:printmessage2:633"></a><a class="pred" href="exception.html#print_message/2">print_message/2</a>
is used to print a message term in a human-readable format. The other
predicates from this section allow the user to refine and extend the
message system. A common usage of
<a id="idx:printmessage2:634"></a><a class="pred" href="exception.html#print_message/2">print_message/2</a>
is to print error messages from exceptions. The code below prints errors
encountered during the execution of <var>Goal</var>, without further
propagating the exception and without starting the debugger.
<pre class="code">
...,
catch(Goal, E,
( print_message(error, E),
fail
)),
...
</pre>
<p>Another common use is to define <a id="idx:messagehook3:635"></a><a class="pred" href="exception.html#message_hook/3">message_hook/3</a>
for printing messages that are normally <em>silent</em>, suppressing
messages, redirecting messages or make something happen in addition to
printing the message.
<dl class="latex">
<dt class="pubdef"><a id="print_message/2"><strong>print_message</strong>(<var>+Kind,
+Term</var>)</a></dt>
<dd class="defbody">
The predicate <a id="idx:printmessage2:636"></a><a class="pred" href="exception.html#print_message/2">print_message/2</a>
is used by the system and libraries to print messages. <var>Kind</var>
describes the nature of the message, while
<var>Term</var> is a Prolog term that describes the content. Printing
messages through this indirection instead of using <a id="idx:format3:637"></a><a class="pred" href="format.html#format/3">format/3</a>
to the stream <code>user_error</code> allows displaying the message
appropriate to the application (terminal, logfile, graphics), acting on
messages based on their content instead of a string (see <a id="idx:messagehook3:638"></a><a class="pred" href="exception.html#message_hook/3">message_hook/3</a>)
and creating language specific versions of the messages. See also
<a class="sec" href="exception.html">section 4.10.3.1</a>. The following
message kinds are known:
<dl class="latex">
<dt><strong>banner</strong></dt>
<dd class="defbody">
The system banner message. Banner messages can be suppressed by setting
the Prolog flag <a class="flag" href="flags.html#flag:verbose">verbose</a>
to <code>silent</code>.</dd>
<dt><strong>debug</strong>(<var>Topic</var>)</dt>
<dd class="defbody">
Message from library(debug). See <a id="idx:debug3:639"></a><a class="pred" href="debug.html#debug/3">debug/3</a>.</dd>
<dt><strong>error</strong></dt>
<dd class="defbody">
The message indicates an erroneous situation. This kind is used to print
uncaught exceptions of type <code>error(Formal, Context)</code>. See
section introduction (<a class="sec" href="exception.html">section
4.10.3</a>).</dd>
<dt><strong>help</strong></dt>
<dd class="defbody">
User requested help message, for example after entering `h' or `?' to a
prompt.</dd>
<dt><strong>information</strong></dt>
<dd class="defbody">
Information that is requested by the user. An example is <a id="idx:statistics0:640"></a><a class="pred" href="statistics.html#statistics/0">statistics/0</a>.</dd>
<dt><strong>informational</strong></dt>
<dd class="defbody">
Typically messages of events are progres that are considered useful to a
developer. Such messages can be suppressed by setting the Prolog flag <a class="flag" href="flags.html#flag:verbose">verbose</a>
to <code>silent</code>.</dd>
<dt><strong>silent</strong></dt>
<dd class="defbody">
Message that is normally not printed. Applications may define
<a id="idx:messagehook3:641"></a><a class="pred" href="exception.html#message_hook/3">message_hook/3</a>
to act upon such messages.</dd>
<dt><strong>trace</strong></dt>
<dd class="defbody">
Messages from the (command line) tracer.</dd>
<dt><strong>warning</strong></dt>
<dd class="defbody">
The message indicates something dubious that is not considered fatal.
For example, discontiguous predicates (see <a id="idx:discontiguous1:642"></a><a class="pred" href="dynamic.html#discontiguous/1">discontiguous/1</a>).
</dd>
</dl>
<p>The predicate <a id="idx:printmessage2:643"></a><a class="pred" href="exception.html#print_message/2">print_message/2</a>
first translates the <var>Term</var> into a list of `message lines' (see <a id="idx:printmessagelines3:644"></a><a class="pred" href="exception.html#print_message_lines/3">print_message_lines/3</a>
for details). Next, it calls the hook <a id="idx:messagehook3:645"></a><a class="pred" href="exception.html#message_hook/3">message_hook/3</a>
to allow the user to intercept the message. If <a id="idx:messagehook3:646"></a><a class="pred" href="exception.html#message_hook/3">message_hook/3</a>
fails it prints the message unless <var>Kind</var> is silent.
<p>The <a id="idx:printmessage2:647"></a><a class="pred" href="exception.html#print_message/2">print_message/2</a>
predicate and its rules are in the file
<code><<var>plhome</var>>/boot/messages.pl</code>, which may be
inspected for more information on the error messages and related error
terms. If you need to write messages from your own predicates, it is
recommended to reuse the existing message terms if applicable. If no
existing message term is applicable, invent a fairly unique term that
represents the event and define a rule for the multifile predicate
prolog:message//1. See
<a class="sec" href="exception.html">section 4.10.3.1</a> for a deeper
discussion and examples.
<p>See also <a id="idx:messagetostring2:648"></a><a class="pred" href="exception.html#message_to_string/2">message_to_string/2</a>.</dd>
<dt class="pubdef"><a id="print_message_lines/3"><strong>print_message_lines</strong>(<var>+Stream,
+Prefix, +Lines</var>)</a></dt>
<dd class="defbody">
Print a message (see <a id="idx:printmessage2:649"></a><a class="pred" href="exception.html#print_message/2">print_message/2</a>)
that has been translated to a list of message elements. The elements of
this list are:
<dl class="latex">
<dt><strong><<var>Format</var>>-<<var>Args</var>></strong></dt>
<dd class="defbody">
Where <var>Format</var> is an atom and <var>Args</var> is a list of
format arguments. Handed to <a id="idx:format3:650"></a><a class="pred" href="format.html#format/3">format/3</a>.
</dd>
<dt><strong>flush</strong></dt>
<dd class="defbody">
If this appears as the last element, <var>Stream</var> is flushed (see <a id="idx:flushoutput1:651"></a><a class="pred" href="chario.html#flush_output/1">flush_output/1</a>)
and no final newline is generated. This is combined with a subsequent
message that starts with
<code>at_same_line</code> to complete the line.
</dd>
<dt><strong>at_same_line</strong></dt>
<dd class="defbody">
If this appears as first element, no prefix is printed for the first
line and the line position is not forced to 0 (see <a id="idx:format1:652"></a><a class="pred" href="format.html#format/1">format/1</a>, <code>~N</code>).
</dd>
<dt><strong>ansi</strong>(<var>+Attributes, +Format, +Args</var>)</dt>
<dd class="defbody">
This message may be intercepted by means of the hook
prolog:message_line_element/2. The library <code>library(ansi_term)</code>
implements this hook to achieve coloured output. If it is not
intercepted it invokes <code>format(Stream, Format, Args)</code>.
</dd>
<dt><strong>nl</strong></dt>
<dd class="defbody">
A new line is started. If the message is not complete,
<var>Prefix</var> is printed before the remainder of the message.
</dd>
<dt><strong>begin</strong>(<var>Kind, Var</var>)</dt>
<dt><strong>end</strong>(<var>Var</var>)</dt>
<dd class="defbody">
The entire message is headed by <code>begin(Kind, Var)</code> and ended
by <code>end(Var)</code>. This feature is used by, e.g., library <code>library(ansi_term)</code>
to colour entire messages.
</dd>
<dt><strong><<var>Format</var>></strong></dt>
<dd class="defbody">
Handed to <a id="idx:format3:653"></a><a class="pred" href="format.html#format/3">format/3</a>
as <code>format(Stream, Format,[])</code>. Deprecated because it is
ambiguous if <var>Format</var> collides with one of the atomic commands.
</dd>
</dl>
<p>See also <a id="idx:printmessage2:654"></a><a class="pred" href="exception.html#print_message/2">print_message/2</a>
and <a id="idx:messagehook3:655"></a><a class="pred" href="exception.html#message_hook/3">message_hook/3</a>.</dd>
<dt class="pubdef"><a id="message_hook/3"><strong>message_hook</strong>(<var>+Term,
+Kind, +Lines</var>)</a></dt>
<dd class="defbody">
Hook predicate that may be defined in the module <code>user</code> to
intercept messages from <a id="idx:printmessage2:656"></a><a class="pred" href="exception.html#print_message/2">print_message/2</a>. <var>Term</var>
and <var>Kind</var> are the same as passed to <a id="idx:printmessage2:657"></a><a class="pred" href="exception.html#print_message/2">print_message/2</a>. <var>Lines</var>
is a list of format statements as described with <a id="idx:printmessagelines3:658"></a><a class="pred" href="exception.html#print_message_lines/3">print_message_lines/3</a>.
See also
<a id="idx:messagetostring2:659"></a><a class="pred" href="exception.html#message_to_string/2">message_to_string/2</a>.
<p>This predicate must be defined dynamic and multifile to allow other
modules defining clauses for it too.</dd>
<dt class="pubdef"><a id="thread_message_hook/3"><strong>thread_message_hook</strong>(<var>+Term,
+Kind, +Lines</var>)</a></dt>
<dd class="defbody">
As <a id="idx:messagehook3:660"></a><a class="pred" href="exception.html#message_hook/3">message_hook/3</a>,
but this predicate is local to the calling thread (see <a id="idx:threadlocal1:661"></a><a class="pred" href="threadcom.html#thread_local/1">thread_local/1</a>).
This hook is called <em>before</em> <a id="idx:messagehook3:662"></a><a class="pred" href="exception.html#message_hook/3">message_hook/3</a>.
The `pre-hook' is indented to catch messages they may be produced by
calling some goal without affecting other threads.</dd>
<dt class="pubdef"><a id="message_property/2"><strong>message_property</strong>(<var>+Kind,
?Property</var>)</a></dt>
<dd class="defbody">
This hook can be used to define additional message kinds and the way
they are displayed. The following properties are defined:
<dl class="latex">
<dt><strong>color</strong>(<var>-Attributes</var>)</dt>
<dd class="defbody">
Print message using ANSI terminal attributes. See <a id="idx:ansiformat3:663"></a><span class="pred-ext">ansi_format/3</span>
for details. Here is an example, printing help messages in blue:
<pre class="code">
:- multifile user:message_property/2.
user:message_property(help, color([fg(blue)])).
</pre>
</dd>
<dt><strong>prefix</strong>(<var>-Prefix</var>)</dt>
<dd class="defbody">
Prefix printed before each line. This argument is handed to <a id="idx:format3:664"></a><a class="pred" href="format.html#format/3">format/3</a>.
The default is <code>'~N'</code>. For example, messages of kind
<code>warning</code> use <code>'~NWarning: '</code>.</dd>
<dt><strong>location_prefix</strong>(<var>+Location, -FirstPrefix,
-ContinuePrefix</var>)</dt>
<dd class="defbody">
Used for printing messages that are related to a source location.
Currently, <var>Location</var> is a term <var>File</var>:<var>Line</var>.
<var>FirstPrefix</var> is the prefix for the first line and
<var>-ContinuePrefix</var> is the prefix for continuation lines. For
example, the default for errors is
<pre class="code">
location_prefix(File:Line, '~NERROR: ~w:~d:'-[File,Line], '~N\t')).
</pre>
</dd>
<dt><strong>stream</strong>(<var>-Stream</var>)</dt>
<dd class="defbody">
Stream to which to print the message. Default is <code>user_error</code>.</dd>
<dt><strong>wait</strong>(<var>-Seconds</var>)</dt>
<dd class="defbody">
Amount of time to wait after printing the message. Default is not to
wait.
</dd>
</dl>
</dd>
<dt class="pubdef"><a id="prolog:message_line_element/2"><strong>prolog:message_line_element</strong>(<var>+Stream,
+Term</var>)</a></dt>
<dd class="defbody">
This hook is called to print the individual elements of a message from
<a id="idx:printmessagelines3:665"></a><a class="pred" href="exception.html#print_message_lines/3">print_message_lines/3</a>.
This hook is used by e.g., library
<code>library(ansi_term)</code> to colour messages on ANSI-capable
terminals.</dd>
<dt class="pubdef"><a id="message_to_string/2"><strong>message_to_string</strong>(<var>+Term,
-String</var>)</a></dt>
<dd class="defbody">
Translates a message term into a string object (see <a class="sec" href="strings.html">section
4.24</a>).</dd>
<dt class="pubdef"><a id="version/0"><strong>version</strong></a></dt>
<dd class="defbody">
Write the SWI-Prolog banner message as well as additional messages
registered using <a id="idx:version1:666"></a><a class="pred" href="exception.html#version/1">version/1</a>.
This is the default <em>initialization goal</em> which can be modified
using <strong>-g</strong>.</dd>
<dt class="pubdef"><a id="version/1"><strong>version</strong>(<var>+Message</var>)</a></dt>
<dd class="defbody">
Register additional messages to be printed by <a id="idx:version0:667"></a><a class="pred" href="exception.html#version/0">version/0</a>.
Each registered message is handed to the message translation DCG and can
thus be defined using the hook prolog:message//1. Of not defined, it is
simply printed.
</dd>
</dl>
<p><h4 id="sec:libprintmsg"><a id="sec:4.10.3.1"><span class="sec-nr">4.10.3.1</span> <span class="sec-title">Printing
from libraries</span></a></h4>
<a id="sec:libprintmsg"></a>
<p>Libraries should <em>not</em> use <a id="idx:format3:668"></a><a class="pred" href="format.html#format/3">format/3</a>
or other output predicates directly. Libraries that print informational
output directly to the console are hard to use from code that depend on
your textual output, such as a CGI script. The predicates in <a class="sec" href="exception.html">section
4.10.3</a> define the API for dealing with messages. The idea behind
this is that a library that wants to provide information about its
status, progress, events or problems calls <a id="idx:printmessage2:669"></a><a class="pred" href="exception.html#print_message/2">print_message/2</a>.
The first argument is the
<em>level</em>. The supported levels are described with <a id="idx:printmessage2:670"></a><a class="pred" href="exception.html#print_message/2">print_message/2</a>.
Libraries typically use <code>informational</code> and <code>warning</code>,
while libraries should use exceptions for errors (see <a id="idx:throw1:671"></a><a class="pred" href="exception.html#throw/1">throw/1</a>, <a id="idx:typeerror2:672"></a><span class="pred-ext">type_error/2</span>,
etc.).
<p>The second argument is an arbitrary Prolog term that carries the
information of the message, but <em>not</em> the precise text. The text
is defined by the grammar rule prolog:message//1. This distinction is
made to allow for translations and to allow hooks processing the
information in a different way (e.g., to translate progress messages
into a progress bar).
<p>For example, suppose we have a library that must download data from
the Internet (e.g., based on <a id="idx:httpopen3:673"></a><span class="pred-ext">http_open/3</span>).
The library wants to print the progress after each downloaded file. The
code below is a good skeleton:
<pre class="code">
download_urls(List) :-
length(List, Total),
forall(nth1(I, List, URL),
( download_url(URL),
print_message(informational,
download_url(URL, I, Total)))).
</pre>
<p>The programmer can now specify the default textual output using the
rule below. Note that this rule may be in the same file or anywhere
else. Notably, the application may come with several rule sets for
different languages. This, and the user-hook example below are the
reason to represent the message as a compound term rather than a string.
This is similar to using message numbers in non-symbolic languages. The
documentation of <a id="idx:printmessagelines3:674"></a><a class="pred" href="exception.html#print_message_lines/3">print_message_lines/3</a>
describes the elements that may appear in the output list.
<pre class="code">
:- multifile
prolog:message//1.
prolog:message(download_url(URL, I, Total)) -->
{ Perc is round(I*100/Total) },
[ 'Downloaded ~w; ~D from ~D (~d%)'-[URL, I, Total, Perc] ].
</pre>
<p>A <em>user</em> of the library may define rules for <a id="idx:messagehook3:675"></a><a class="pred" href="exception.html#message_hook/3">message_hook/3</a>.
The rule below acts on the message content. Other applications can act
on the message level and, for example, popup a message box for warnings
and errors.
<pre class="code">
:- multifile user:message_hook/3.
message_hook(download_url(URL, I, Total), _Kind, _Lines) :-
<send this information to a GUI component>
</pre>
<p>In addition, using the command line option <strong>-q</strong>, the
user can disable all <em>informational</em> messages.
<p></body></html>
|