root/trunk/manuals/userman/objects.html

Revision 4621, 25.3 KB (checked in by pmoura, 6 weeks ago)

Improved navigation bar in the XHTML manual pages.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4
5<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
6
7<head>
8    <meta http-equiv="content-type" content="application/xml+xhtml; charset=utf-8" />
9    <title>Logtalk user manual: objects</title>
10    <link rel="stylesheet" href="../screen.css" type="text/css" media="screen"/>
11    <link rel="stylesheet" href="../print.css" type="text/css" media="print"/>
12</head>
13
14<body>
15
16<div class="top-left">Logtalk user manual</div> 
17<div class="top-right">Objects</div>
18<div class="bottom-left"><span class="page"/></div> 
19<div class="bottom-right"><span class="page"/></div>
20<div class="navtop"><a href="../index.html">Contents</a> &gt; <a href="index.html">User Manual</a> &gt; Objects</div>
21
22<h1 id="objects_objects">Objects</h1>
23
24<p>
25The main goal of Logtalk objects is the encapsulation and reuse of predicates. Instead of a single database containing all your code, Logtalk objects provide separated namespaces or databases allowing the partitioning of code in more manageable parts. Logtalk does not aim to bring some sort of new dynamic state change concept to Logic Programming or Prolog.
26</p>
27<p>
28In Logtalk, the only pre-defined objects are the built-in objects <code>user</code>, <code>debugger</code>, and <code>logtalk</code>, which are described at the end of this section.
29</p>
30
31<h2 id="objects_kind">Objects, prototypes, classes, and instances</h2>
32
33<p>
34There are only three kinds of encapsulation entities in Logtalk: objects, protocols, and categories. Logtalk uses the term <em>object</em> in a broad sense. The terms <em>prototype</em>, <em>parent</em>, <em>class</em>, <em>subclass</em>, <em>superclass</em>, <em>metaclass</em>, and <em>instance</em> always designate an object. Different names are used to emphasize the <em>role</em> played by an object in a particular context. I.e. we use a term other than object when we want to make the relationship with other objects explicit. For example, an object with an <em>instantiation</em> relation with other object plays the role of an <em>instance</em>, while the instantiated object plays the role of a <em>class</em>; an object with a <em>specialization</em> relation other object plays the role of a <em>subclass</em>, while the specialized object plays the role of a <em>superclass</em>; an object with an <em>extension</em> relation with other object plays the role of a <em>prototype</em>, the same for the extended object. A <em>stand-alone</em> object, i.e. an object with no relations with other objects, is always interpreted as a prototype. In Logtalk, entity relations essentially define <em>patterns</em> of code reuse. An entity is compiled accordingly to the roles it plays.
35</p>
36<p>
37Logtalk allows you to work from standalone objects to any kind of hierarchy, either class-based or prototype-based. You may use single or multiple inheritance, use or forgo metaclasses, implement reflective designs, use parametric objects, and take advantage of protocols and categories (think components).
38</p>
39
40<h3 id="objects_prototypes">Prototypes</h3>
41
42<p>
43Prototypes are either self-defined objects or objects defined as extensions to other prototypes with whom they share common properties. Prototypes are ideal for representing one-of-a-kind objects. Prototypes usually represent concrete objects in the application domain. When linking prototypes using <em>extension</em> relations, Logtalk uses the term <em>prototype hierarchies</em> although most authors prefer to use the term <em>hierarchy</em> only with class generalization/specialization relations. In the context of logic programming, prototypes are often the ideal replacement for modules.
44</p>
45
46<h3 id="objects_classes">Classes</h3>
47
48<p>
49Classes are used to represent abstractions of common properties of sets of objects. Classes provide an ideal structuring solution when you want to express hierarchies of abstractions or work with many similar objects. Classes are used indirectly through <em>instantiation</em>. Contrary to most object-oriented programming languages, instances can be created both dynamically at runtime or defined in a source file like other objects.
50</p>
51
52<h2 id="objects_defining">Defining a new object</h2>
53
54<p>
55We can define a new object in the same way we write Prolog code: by using a text editor. Logtalk source files may contain one or more objects, categories, or protocols. If you prefer to define each entity in its own source file, it is recommended that the file be named after the object. By default, all Logtalk source files use the extension <code>.lgt</code> but this is optional and can be set in the configuration files. Intermediate Prolog source files (generated by the Logtalk compiler) have, by default, a <code>.pl</code> extension. Again, this can be set to match the needs of a particular Prolog compiler in the corresponding configuration file. For instance, we may define an object named <code>vehicle</code> and save it in a <code>vehicle.lgt</code> source file which will be compiled to a <code>vehicle.pl</code> Prolog file.
56</p>
57<p>
58Object names can be atoms or compound terms (when defining parametric objects, see below). Objects, categories, and protocols share the same name space: we cannot have an object with the same name as a protocol or a category.
59</p>
60<p>
61Object code (directives and predicates) is textually encapsulated by using two Logtalk directives: <a title="Consult reference manual" href="../refman/directives/object1_5.html"><code>object/1-5</code></a> and <a title="Consult reference manual" href="../refman/directives/end_object0.html"><code>end_object/0</code></a>. The most simple object will be one that is self-contained, not depending on any other Logtalk entity:
62</p>
63<pre>:- object(Object).
64    ...
65:- end_object.</pre>
66<p>
67If an object implements one or more protocols then the opening directive will be:
68</p>
69<pre>:- object(Object,
70    implements(Protocol)).
71    ...
72:- end_object.</pre>
73<p>
74An object can import one or more categories:
75</p>
76<pre>:- object(Object,
77    imports(Category)).
78    ...
79:- end_object.</pre>
80<p>
81If an object both implements protocols and imports categories then we will write:
82</p>
83<pre>:- object(Object,
84    implements(Protocol),
85    imports(Category)).
86    ...
87:- end_object.</pre>
88<p>
89In object-oriented programming objects are usually organized in hierarchies that enable interface and code sharing by inheritance. In Logtalk, we can construct prototype-based hierarchies by writing:
90</p>
91<pre>:- object(Prototype,
92    extends(Parent)).
93    ...
94:- end_object.</pre>
95<p>
96We can also have class-based hierarchies by defining instantiation and specialization relations between objects. To define an object as a class instance we will write:
97</p>
98<pre>:- object(Object,
99    instantiates(Class)).
100    ...
101:- end_object.</pre>
102<p>
103A class may specialize another class, its superclass:
104</p>
105<pre>:- object(Class,
106    specializes(Superclass)).
107    ...
108:- end_object.</pre>
109<p>
110If we are defining a reflexive system where every class is also an instance, we will probably be using the following pattern:
111</p>
112<pre>:- object(Class,
113    instantiates(Metaclass),
114    specializes(Superclass)).
115    ...
116:- end_object.</pre>
117<p>
118In short, an object can be a <em>stand-alone</em> object or be part of an object hierarchy. The hierarchy can be prototype-based (defined by extending other objects) or class-based (with instantiation and specialization relations). An object may also implement one or more protocols or import one or more categories.
119</p>
120<p>
121A <em>stand-alone</em> object (i.e. an object with no extension, instantiation, or specialization relations with other objects) is always compiled as a prototype, that is, a self-describing object. If we want to use classes and instances, then we will need to specify at least one instantiation or specialization relation. The best way to do this is to define a set of objects that provide the basis of a reflective system <a href="../bibliography.html#Cointe87">[Cointe 87</a>, <a href="../bibliography.html#Moura94">Moura 94]</a>. For example:
122</p>
123<pre>:- object(object,               % default root of the inheritance graph
124    instantiates(class)).       % predicates common to all objects
125    ...
126:- end_object.
127
128
129:- object(class,                % default metaclass for all classes
130    instantiates(class),        % predicates common to all instantiable classes
131    specializes(abstract_class)).
132    ...
133:- end_object.
134
135
136:- object(abstract_class,       % default metaclass for all abstract classes
137    instantiates(class),        % predicates common to all classes
138    specializes(object)).
139    ...
140:- end_object.</pre>
141<p>
142Note that with these instantiation and specialization relations, <code>object</code>, <code>class</code>, and <code>abstract_class</code> are, at the same time, classes and instances of some class. In addition, each object inherits its own predicates and the predicates of the other two objects without any inheritance loop problems.
143</p>
144<p>
145When a full-blown reflective system solution is not needed, the above scheme can be simplified by making an object an instance of itself, i.e. by making a class its own metaclass. For example:
146</p>
147<pre>:- object(class,
148    instantiates(class)).
149    ...
150:- end_object.</pre>
151<p>
152A third alternative is to use neither metaclasses or reflective designs but instead to take advantage of the built-in object <code>logtalk</code>. This empty object can be used as a dummy root superclass. For example:
153</p>
154<pre>:- object(class,
155    specializes(logtalk)).
156    ...
157:- end_object.</pre>
158<p>
159We can use, in the same application, both prototype and class-based hierarchies (and freely exchange messages between all objects). We cannot however mix the two types of hierarchies by, e.g., specializing an object that extends another object in this current Logtalk version.
160</p>
161
162<h2 id="objects_parametric">Parametric objects</h2>
163
164<p>
165Parametric objects have a compound term for name instead of an atom. This compound term usually contains free variables that can be instantiated when sending a message to the object, thus acting as object parameters. The object predicates can then be coded to depend on the parameter values. When an object state is set at object creation and never changed, parameters provide a better solution than using the object's database via asserts. Parametric objects can also be used to associate a set of predicates to terms that share a common functor and arity.
166</p>
167<p>
168In order to give access to an object parameters, Logtalk provides the <a title="Consult reference manual" href="../refman/methods/parameter2.html"><code>parameter/2</code></a> built-in local method:
169</p>
170<pre>:- object(Functor(Arg1, Arg2, ...)).
171
172    ...
173
174    Predicate :-
175        ...,
176        parameter(Number, Value),
177        ... .</pre>
178<p>
179An alternative solution is to use the built-in local method <a title="Consult reference manual" href="../refman/methods/this1.html"><code>this/1</code></a>. For example:
180</p>
181<pre>:- object(foo(Arg)).
182
183    ...
184
185    bar :-
186        ...,
187        this(foo(Arg)),
188        ... .</pre>
189<p>
190Both solutions are equally efficient because the runtime cost of the methods <code>this/1</code> and <code>parameter/2</code> is negligible. The drawback of this second solution is that we must check all calls of <code>this/1</code> if we change the object name. Note that we can't use these method with the message sending operators (<a title="Consult reference manual" href="../refman/control/to_object2.html"><code>::/2</code></a>, <a title="Consult reference manual" href="../refman/control/to_self1.html"><code>::/1</code></a>, or <a title="Consult reference manual" href="../refman/control/to_object2.html"><code>^^/1</code></a>).
191</p>
192<p>
193When storing a parametric object in its own source file, the convention is to name the file after the object, with the object arity appended. For instance, when defining an object named <code>sort(Type)</code>, we may save it in a <code>sort_1.lgt</code> text file. This way it is easy to avoid file name clashes when saving Logtalk entities that have the same functor but different arity.
194</p>
195<p>
196Compound terms with the same functor and (usually) the same number of arguments as a parametric object identifier may act as <em>proxies</em> to a parametric object. Proxies may be stored on the database as Prolog facts and be used to represent different instantiations of a parametric object identifier. Logtalk provides a convenient notation for accessing proxies represented as Prolog facts when sending a message:
197</p>
198<pre>{Proxy}::Message</pre>
199<p>
200In this context, the proxy argument is proved as a plain, deterministic Prolog goal. If successful, the message is sent to the corresponding parametric object. Typically, the proof allows retrieving of parameter instantiations. This construct should be used with a proxy argument that is sufficiently instantiated in order to unify with a single Prolog fact.
201</p>
202
203<h2 id="objects_finding">Finding defined objects</h2>
204
205<p>
206We can find, by backtracking, all defined objects by calling the <a title="Consult reference manual" href="../refman/builtins/current_object1.html"><code>current_object/1</code></a> built-in predicate with an uninstantiated variable:
207</p>
208<pre>| ?- current_object(Object).</pre>
209<p>
210This predicate can also be used to test if an object is defined by calling it with a valid object identifier (an atom or a compound term).
211</p>
212
213<h2 id="objects_creating">Creating a new object in runtime</h2>
214
215<p>
216An object can be dynamically created at runtime by using the <a title="Consult reference manual" href="../refman/builtins/create_object4.html"><code>create_object/4</code></a> built-in predicate:
217</p>
218<pre>| ?- create_object(Object, Relations, Directives, Clauses).</pre>
219<p>
220The first argument should be either a variable or the name of the new object (a Prolog atom or compound term, which must not match any existing entity name). The remaining three arguments correspond to the relations described in the opening object directive and to the object code contents (directives and clauses).
221</p>
222<p>
223For instance, the call:
224</p>
225<pre>| ?- create_object(foo, [extends(bar)], [public(foo/1)], [foo(1), foo(2)]).</pre>
226<p>
227is equivalent to compiling and loading the object:
228</p>
229<pre>:- object(foo,
230    extends(bar)).
231
232    :- dynamic.
233
234    :- public(foo/1).
235
236    foo(1).
237    foo(2).
238
239:- end_object.</pre>
240<p>
241If we need to create a lot of (dynamic) objects at runtime, then is best to define a metaclass or a prototype with a predicate that will call this built-in predicate to make new objects. This predicate may provide automatic object name generation, name checking, and accept object initialization options.
242</p>
243
244<h2 id="objects_abolishing">Abolishing an existing object</h2>
245
246<p>
247Dynamic objects can be abolished using the <a title="Consult reference manual" href="../refman/builtins/abolish_object1.html"><code>abolish_object/1</code></a> built-in predicate:
248</p>
249<pre>| ?- abolish_object(Object).</pre>
250<p>
251The argument must be an identifier of a defined dynamic object, otherwise an error will be thrown.
252</p>
253
254<h2 id="objects_directives">Object directives</h2>
255
256<p>
257Object directives are used to set initialization goals and object properties and to document an object dependencies on other Logtalk entities.
258</p>
259
260<h3 id="objects_initialization">Object initialization</h3>
261
262<p>
263We can define a goal to be executed as soon as an object is (compiled and) loaded to memory with the <a title="Consult reference manual" href="../refman/directives/initialization1.html"><code>initialization/1</code></a> directive:
264</p>
265<pre>:- initialization(Goal).</pre>
266<p>
267The argument can be any valid Prolog or Logtalk goal, including a message to other object. For example:
268</p>
269<pre>:- object(foo).
270
271    :- initialization(init).
272    :- private(init/0).
273
274    init :-
275        ... .
276
277    ...
278
279:- end_object.</pre>
280<p>
281Or:
282</p>
283<pre>:- object(assembler).
284
285    :- initialization(control::start).
286    ...
287
288:- end_object.</pre>
289<p>
290The initialization goal can also be a message to <i>self</i> in order to call an inherited or imported predicate. For example, assuming that we have a <code>monitor</code> category defining a <code>reset/0</code> predicate:
291</p>
292<pre>:- object(profiler,
293    imports(monitor)).
294
295    :- initialization(::reset).
296    ...
297
298:- end_object.</pre>
299<p>
300Note, however, that descendant objects do not inherit initialization directives. In this context, <i>self</i> denotes the object that contains the directive. Also note that by initialization we do not necessarily mean setting an object dynamic state.
301</p>
302 
303<h3 id="objects_synchronized">Synchronized objects</h3>
304
305<p>
306When doing multi-threading programming, is possible to synchronize all the predicates of an object using the <a title="Consult reference manual" href="../refman/directives/synchronized0.html"><code>synchronized/0</code></a> directive in the object source code:
307</p>
308<pre>:- synchronized.</pre>
309<p>
310This directive results in using internally the same mutex for synchronizing the execution of all defined object predicates. For fine-grained predicate synchronization, the <a title="Consult reference manual" href="../refman/directives/synchronized1.html"><code>synchronized/1</code></a> directive may be used instead.
311</p>
312
313<h3 id="objects_dynamic">Dynamic objects</h3>
314
315<p>
316Similar to Prolog predicates, an object can be either static or dynamic. An object created during the execution of a program is always dynamic. An object defined in a file can be either dynamic or static. Dynamic objects are declared by using the <a title="Consult reference manual" href="../refman/directives/dynamic0.html"><code>dynamic/0</code></a> directive in the object source code:
317</p>
318<pre>:- dynamic.</pre>
319<p>
320The directive must precede any predicate directives or clauses. Please be aware that using dynamic code results in a performance hit when compared to static code. We should only use dynamic objects when these need to be abolished during program execution. In addition, note that we can declare and define dynamic predicates within a static object.
321</p>
322
323<h3 id="objects_dependencies">Object dependencies</h3>
324
325<p>
326Besides the relations declared in the object opening directive, the predicate definitions contained in the object may imply other dependencies. These can be documented by using the <a title="Consult reference manual" href="../refman/directives/calls1.html"><code>calls/1</code></a> and the <a title="Consult reference manual" href="../refman/directives/uses1.html"><code>uses/1</code></a> directives.
327</p>
328<p>
329The <code>calls/1</code> directive can be used when a predicate definition sends a message that is declared in a specific protocol:
330</p>
331<pre>:- calls(Protocol).</pre>
332<p>
333If a predicate definition sends a message to a specific object, this dependence can be declared with the <code>uses/1</code> directive:
334</p>
335<pre>:- uses(Object).</pre>
336<p>
337These two directives may be used by the Logtalk runtime to ensure that all needed entities are loaded when running an application.
338</p>
339
340<h3 id="objects_documentation">Object documentation</h3>
341
342<p>
343An object can be documented with arbitrary user-defined information by using the <a title="Consult reference manual" href="../refman/directives/info1.html"><code>info/1</code></a> directive:
344</p>
345<pre>:- info(List).</pre>
346<p>
347See the <a href="documenting.html">documenting Logtalk programs</a> session for details.
348</p>
349
350<h2 id="objects_relationships">Object relationships</h2>
351
352<p>
353Logtalk provides six sets of built-in predicates that enable us to query the system about the possible relationships that an object may have with other entities.
354</p>
355<p>
356The built-in predicates <a title="Consult reference manual" href="../refman/builtins/instantiates_class2_3.html"><code>instantiates_class/2</code></a> and <a title="Consult reference manual" href="../refman/builtins/instantiates_class2_3.html"><code>instantiates_class/3</code></a> can be used to query all instantiation relations:
357</p>
358<pre>| ?- instantiates_class(Instance, Class).</pre>
359<p>
360or, if we want to know the instantiation scope:
361</p>
362<pre>| ?- instantiates_class(Instance, Class, Scope).</pre>
363<p>
364Specialization relations can be found by using either the <a title="Consult reference manual" href="../refman/builtins/specializes_class2_3.html"><code>specializes_class/2</code></a> or the <a title="Consult reference manual" href="../refman/builtins/specializes_class2_3.html"><code>specializes_class/3</code></a> built-in predicates:
365</p>
366<pre>| ?- specializes_class(Class, Superclass).</pre>
367<p>
368or, if we want to know the specialization scope:
369</p>
370<pre>| ?- specializes_class(Class, Superclass, Scope).</pre>
371<p>
372For prototypes, we can query extension relations with the <a title="Consult reference manual" href="../refman/builtins/extends_object2_3.html"><code>extends_object/2</code></a> or the <a title="Consult reference manual" href="../refman/builtins/extends_object2_3.html"><code>extends_object/3</code></a> built-in predicates:
373</p>
374<pre>| ?- extends_object(Object, Parent).</pre>
375<p>
376or, if we want to know the extension scope:
377</p>
378<pre>| ?- extends_object(Object, Parent, Scope).</pre>
379<p>
380In order to find which objects import which categories we can use the built-in predicates <a title="Consult reference manual" href="../refman/builtins/imports_category2_3.html"><code>imports_category/2</code></a> or <a title="Consult reference manual" href="../refman/builtins/imports_category2_3.html"><code>imports_category/3</code></a>:
381</p>
382<pre>| ?- imports_category(Object, Category).</pre>
383<p>
384or, if we want to know the importation scope:
385</p>
386<pre>| ?- imports_category(Object, Category, Scope).</pre>
387<p>
388To find which objects implements which protocols we can use the <a title="Consult reference manual" href="../refman/builtins/implements_protocol2_3.html"><code>implements_protocol/2</code></a> or the <a title="Consult reference manual" href="../refman/builtins/implements_protocol2_3.html"><code>implements_protocol/3</code></a> built-in predicates:
389</p>
390<pre>| ?- implements_protocol(Object, Protocol).</pre>
391<p>
392or, if we want to know the implementation scope:
393</p>
394<pre>| ?- implements_protocol(Object, Protocol, Scope).</pre>
395<p>
396Note that, if we use an uninstantiated variable for the first argument, we will need to use the <a title="Consult reference manual" href="../refman/builtins/current_object1.html"><code>current_object/1</code></a> built-in predicate to ensure that the entity returned is an object and not a category.
397</p>
398<p>
399To find which objects are explicitly complement by categories we can use the
400<a title="Consult reference manual" href="../refman/builtins/complements_object2.html"><code>complements_object/2</code></a> built-in predicate:
401</p>
402<pre>| ?- complements_object(Category, Object).</pre>
403<p>
404Note that more than one category may explicitly complement a single object.
405</p>
406
407
408<h2 id="objects_properties">Object properties</h2>
409
410<p>
411We can find the properties of defined objects by calling the built-in predicate <a title="Consult reference manual" href="../refman/builtins/object_property2.html"><code>object_property/2</code></a>:
412</p>
413<pre>| ?- object_property(Object, Property).</pre>
414<p>
415An object may have the property <code>static</code>, <code>dynamic</code>, or <code>built_in</code>. Dynamic objects can be abolished in runtime by calling the <a title="Consult reference manual" href="../refman/builtins/abolish_object1.html"><code>abolish_object/1</code></a> built-in predicate. An object may also have the properties <code>synchronized</code> and <code>threaded</code>, which are related to multi-threading programming. Depending on the back-end Prolog compiler, an object may have additional properties related to the source file where it is defined.
416</p>
417
418<h2 id="objects_built_in">Built-in objects</h2>
419
420<p>
421Logtalk defines some built-in objects that are always available for any application.
422</p>
423
424<h3 id="objects_user">The built-in pseudo-object <em>user</em></h3>
425
426<p>
427Logtalk defines a built-in, pseudo-object named <code>user</code> that contains all user predicate definitions not encapsulated in a Logtalk entity. These predicates are assumed to be implicitly declared public.
428</p>
429
430<h3 id="objects_debugger">The built-in object <em>debugger</em></h3>
431
432<p>
433Logtalk defines a built-in object named <code>debugger</code> which implements the Logtalk built-in debugger (see the section on <a href="programming.html#programming_debugging">debugging Logtalk programs</a> for details). This object is virtually compiled as a prototype. Programmers may define new prototypes extending <code>debugger</code> in order to implement custom debuggers.
434</p>
435
436<h3 id="objects_logtalk">The built-in object <em>logtalk</em></h3>
437
438<p>
439Logtalk defines an empty built-in object named <code>logtalk</code>, which can play the role of both a class and a prototype. It may be used to define class hierarchies without forcing the use of metaclasses or reflective designs, as illustrated above. This object supports the dynamic declaration and definition of predicates (using the dynamic database built-in methods).
440</p>
441
442<div class="footer">
443    <div class="copyright">
444        <span>Copyright &copy; <a href="mailto:pmoura@logtalk.org">Paulo Moura</a> &mdash; <a href="http://logtalk.org">Logtalk.org</a></span><br/> 
445        <span>Last updated on: October 20, 2008</span>
446    </div>
447    <div class="navbottom">
448        <span><a href="messages.html">previous</a> | <a href="../glossary.html">glossary</a> | <a href="protocols.html">next</a></span><br/>
449        <span><a href="http://validator.w3.org/check/referer">XHTML</a> + <a href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a></span>
450    </div>
451</div>
452
453</body>
454
455</html>
Note: See TracBrowser for help on using the browser.