Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > by-pkgid > 2fc07611b08d4a735fd34d5eb60d8e16 > files > 2060

ciao-1.10p8-3mdv2010.0.i586.rpm

<HTML>
<HEAD>
<!-- Created by texi2html 1.56k + clip patches and <A href="http://www.clip.dia.fi.upm.es/Software">lpdoc</A> from ciao.texi on 28 January 2007 -->

<LINK rel="stylesheet" href="ciao.css" type="text/css">
<TITLE>The Ciao Prolog System               - Run time usage of objects</TITLE>
</HEAD>
<BODY> 
Go to the <A HREF="ciao_1.html">first</A>, <A HREF="ciao_116.html">previous</A>, <A HREF="ciao_118.html">next</A>, <A HREF="ciao_241.html">last</A> section, <A HREF="ciao_toc.html">table of contents</A>.
<P><HR><P>


<H1><A NAME="SEC492" HREF="ciao_toc.html#TOC492">Run time usage of objects</A></H1>
<P>
<A NAME="IDX5668"></A>


<P>
<STRONG>Author(s):</STRONG> Angel Fernandez Pineda, Angel Fernandez Pineda.


<P>
<STRONG>Version:</STRONG> 1.10#7 (2006/4/26, 19:22:13 CEST)


<P>
<STRONG>Version of last change:</STRONG> 1.7#51 (2001/1/25, 21:33:0 CET)


<P>
This library provides run-time support for 
<A NAME="IDX5669"></A>
object creation and manipulation. Objects are also called 
<A NAME="IDX5670"></A>
class instances, or simply 
<A NAME="IDX5671"></A>
instances. 


<P>
Objects in Ciao are treated as normal modules. This is, an object is a run-time generated Prolog module, which may be identified by an unique term across the whole application. 


<P>
This is a very simple example of how to create an instance, and how to make calls to it: 



<PRE>
            AnObj new myclass,
            AnObj:mymethod.
</PRE>

<P>
In order to make any object accessible from code, an usage relationship must be established between the class (from which instances are derived) and the code itself. Refer to 
<A NAME="IDX5672"></A>
<CODE>use_class/1</CODE> predicate or 
<A NAME="IDX5673"></A>
<CODE>use_class/1</CODE> declaration in order to do so. 



<UL>
<LI><A HREF="ciao_117.html#SEC493">Usage and interface (objects_rt)</A>
<LI><A HREF="ciao_117.html#SEC494">Documentation on exports (objects_rt)</A>
<LI><A HREF="ciao_117.html#SEC495">Known bugs and planned improvements (objects_rt)</A>
</UL>



<H2><A NAME="SEC493" HREF="ciao_toc.html#TOC493">Usage and interface (<CODE>objects_rt</CODE>)</A></H2>

<div class="cartouche">

<UL>

<LI><STRONG>Library usage:</STRONG>

This library is automatically loaded when using the <EM>objects</EM> package: 

<PRE>
    :- module(<EM>ModuleName</EM>,<EM>Exports</EM>,[objects]).
</PRE>

Nothing special needs to be done. 

<LI><STRONG>Exports:</STRONG>


<UL>

<LI><EM>Predicates:</EM>

<A NAME="IDX5674"></A>
<CODE>new/2</CODE>, 
<A NAME="IDX5675"></A>
<CODE>instance_of/2</CODE>, 
<A NAME="IDX5676"></A>
<CODE>derived_from/2</CODE>, 
<A NAME="IDX5677"></A>
<CODE>interface/2</CODE>, 
<A NAME="IDX5678"></A>
<CODE>instance_codes/2</CODE>, 
<A NAME="IDX5679"></A>
<CODE>destroy/1</CODE>, 
<A NAME="IDX5680"></A>
<CODE>use_class/1</CODE>.

<LI><EM>Properties:</EM>

<A NAME="IDX5681"></A>
<CODE>constructor/1</CODE>, 
<A NAME="IDX5682"></A>
<CODE>class_name/1</CODE>, 
<A NAME="IDX5683"></A>
<CODE>interface_name/1</CODE>, 
<A NAME="IDX5684"></A>
<CODE>instance_id/1</CODE>, 
<A NAME="IDX5685"></A>
<CODE>class_source/1</CODE>, 
<A NAME="IDX5686"></A>
<CODE>interface_source/1</CODE>, 
<A NAME="IDX5687"></A>
<CODE>method_spec/1</CODE>, 
<A NAME="IDX5688"></A>
<CODE>virtual_method_spec/1</CODE>.

</UL>

<LI><STRONG>Other modules used:</STRONG>


<UL>

<LI><EM>System library modules:</EM>

<A NAME="IDX5689"></A>
<CODE>operators</CODE>, 
<A NAME="IDX5690"></A>
<CODE>default_predicates</CODE>, 
<A NAME="IDX5691"></A>
<CODE>compiler/compiler</CODE>, 
<A NAME="IDX5692"></A>
<CODE>prolog_sys</CODE>, 
<A NAME="IDX5693"></A>
<CODE>system</CODE>.

</UL>

</UL>

</div class="cartouche">



<H2><A NAME="SEC494" HREF="ciao_toc.html#TOC494">Documentation on exports (<CODE>objects_rt</CODE>)</A></H2>
<P>
<A NAME="IDX5694"></A>
<A NAME="IDX5695"></A>
<DL>
<DT><span class="define">PREDICATE:</span> <B>new/2:</B>
<DD><A NAME="IDX5696"></A>


<P>
Dynamic instance creation takes place by the ways of this predicate. 


<P>
It takes a free variable as first argument which will be instantiated to an internal object identifier. 


<P>
Second argument must be instantiated to a 
<A NAME="IDX5697"></A>
class constructor. Class constructors are designed to perform an initialization on the new created instance. Notice that instance initialization may involve some kind of computation, not only <EM>state initialization</EM>. 


<P>
A class constructor is made by a functor, which must match the intended class name, and any number of parameters. For example: 



<PRE>
            Obj new myclass(1500,'hello, world!!!')
</PRE>

<P>
Those parameters depends (obviously) on the constructors defined at the class source. If no constructors where defined, no parameters are needed. This is called the 
<A NAME="IDX5698"></A>
default constructor. An example: 



<PRE>
            Obj new myclass
</PRE>

<P>
The default constructor can not be called if there is any constructor available at the class source. 


<P>
Instantiation will raise an exception and fail whenever any of this conditions occur: 

<UL>
<LI>First argument is not a free variable.

<LI>Second argument functor is a class, but there is no usage relationship with it.

<LI>Second argument functor is not a class.

<LI>The given constructor is unknown.

<LI>The given constructor fails (notice that default constructor never fails).

</UL>

<P>
Objects may also be statically declared, refer to 
<A NAME="IDX5699"></A>
<CODE>instance_of/2</CODE> declaration. 


<P>
<STRONG>Usage:</STRONG> <CODE>new(InstanceVar, Constructor)</CODE>

<UL>
<LI><EM>Description:</EM> Creates a new instance of the class specified by <CODE>Constructor</CODE> returning its identifier in <CODE>InstanceVar</CODE>

<LI><EM>The following properties should hold at call time:</EM>

<CODE>InstanceVar</CODE> is a free variable.
 (<CODE>term_typing:var/1</CODE>)

<CODE>Constructor</CODE> is a term whose functor matches a class name.
 (<CODE>objects_rt:constructor/1</CODE>)
<LI><EM>The following properties should hold upon exit:</EM>

<CODE>InstanceVar</CODE> is an unique term which identifies an object.
 (<CODE>objects_rt:instance_id/1</CODE>)
</UL>

</DL>

<P>
<A NAME="IDX5700"></A>
<A NAME="IDX5701"></A>
<DL>
<DT><span class="define">PREDICATE:</span> <B>instance_of/2:</B>
<DD><A NAME="IDX5702"></A>


<P>
This predicate is used to perform dynamic type checking. You may check whether a particular instance belongs to a particular class or related descendants. 


<P>
instance_of/2 is used to perform static 
<A NAME="IDX5703"></A>
semantic analisys over object oriented code constructions. 


<P>
By the use of instance_of/2 you may help to perform such analisys. 


<P>
<STRONG>Usage 1:</STRONG> <CODE>instance_of(Instance, Class)</CODE>

<UL>
<LI><EM>Description:</EM> Test whether <CODE>Instance</CODE> was derived from any descendant of <CODE>Class</CODE>, or that class itself

<LI><EM>The following properties should hold at call time:</EM>

<CODE>Instance</CODE> is an unique term which identifies an object.
 (<CODE>objects_rt:instance_id/1</CODE>)

<CODE>Class</CODE> is an atom denoting a class.
 (<CODE>objects_rt:class_name/1</CODE>)
</UL>

<P>
<STRONG>Usage 2:</STRONG> <CODE>instance_of(Instance, Class)</CODE>

<UL>
<LI><EM>Description:</EM> Retrieves, on backtracking, the inheritance line of <CODE>Instance</CODE> commencing on the creation class (that specified on call to

<A NAME="IDX5704"></A>
<CODE>new/2</CODE>) and continuing on the rest of ascendant classes, if any. 
<LI><EM>The following properties should hold at call time:</EM>

<CODE>Instance</CODE> is an unique term which identifies an object.
 (<CODE>objects_rt:instance_id/1</CODE>)

<CODE>Class</CODE> is a free variable.
 (<CODE>term_typing:var/1</CODE>)
<LI><EM>The following properties should hold upon exit:</EM>

<CODE>Class</CODE> is an atom denoting a class.
 (<CODE>objects_rt:class_name/1</CODE>)
</UL>

</DL>

<P>
<A NAME="IDX5705"></A>
<A NAME="IDX5706"></A>
<DL>
<DT><span class="define">PREDICATE:</span> <B>derived_from/2:</B>
<DD><A NAME="IDX5707"></A>


<P>
Test whether an object identifier was derived directly from a class, by the usage of 
<A NAME="IDX5708"></A>
<CODE>new/2</CODE> or a static instance declaration (
<A NAME="IDX5709"></A>
<CODE>instance_of/2</CODE>). 


<P>
<STRONG>Usage 1:</STRONG> <CODE>derived_from(Instance, Class)</CODE>

<UL>
<LI><EM>Description:</EM> Test derivation of <CODE>Instance</CODE> from <CODE>Class</CODE>

<LI><EM>The following properties should hold at call time:</EM>

<CODE>Instance</CODE> is an unique term which identifies an object.
 (<CODE>objects_rt:instance_id/1</CODE>)

<CODE>Class</CODE> is an atom denoting a class.
 (<CODE>objects_rt:class_name/1</CODE>)
</UL>

<P>
<STRONG>Usage 2:</STRONG> <CODE>derived_from(Instance, Class)</CODE>

<UL>
<LI><EM>Description:</EM> Retrieves the <CODE>Class</CODE> responsable of the derivation of <CODE>Instance</CODE>.

<LI><EM>The following properties should hold at call time:</EM>

<CODE>Instance</CODE> is an unique term which identifies an object.
 (<CODE>objects_rt:instance_id/1</CODE>)

<CODE>Class</CODE> is a free variable.
 (<CODE>term_typing:var/1</CODE>)
<LI><EM>The following properties should hold upon exit:</EM>

<CODE>Class</CODE> is an atom denoting a class.
 (<CODE>objects_rt:class_name/1</CODE>)
</UL>

</DL>

<P>
<A NAME="IDX5710"></A>
<A NAME="IDX5711"></A>
<DL>
<DT><span class="define">PREDICATE:</span> <B>interface/2:</B>
<DD><A NAME="IDX5712"></A>


<P>
This predicate is used to ensure a given interface to be implemented by a given instance. 


<P>
<STRONG>Usage 1:</STRONG> <CODE>interface(Instance, Interface)</CODE>

<UL>
<LI><EM>Description:</EM> Check whether <CODE>Instance</CODE> implements the given <CODE>Interface</CODE>.

<LI><EM>The following properties should hold at call time:</EM>

<CODE>Instance</CODE> is an unique term which identifies an object.
 (<CODE>objects_rt:instance_id/1</CODE>)

<CODE>Interface</CODE> is an unique atom which identifies a public interface.
 (<CODE>objects_rt:interface_name/1</CODE>)
</UL>

<P>
<STRONG>Usage 2:</STRONG> <CODE>interface(Instance, Interfaces)</CODE>

<UL>
<LI><EM>Description:</EM> Retrieves on backtracking all the implemented <CODE>Interfaces</CODE> of <CODE>Instance</CODE>.

<LI><EM>The following properties should hold at call time:</EM>

<CODE>Instance</CODE> is an unique term which identifies an object.
 (<CODE>objects_rt:instance_id/1</CODE>)

<CODE>Interfaces</CODE> is a free variable.
 (<CODE>term_typing:var/1</CODE>)
<LI><EM>The following properties should hold upon exit:</EM>

<CODE>Interfaces</CODE> is an unique atom which identifies a public interface.
 (<CODE>objects_rt:interface_name/1</CODE>)
</UL>

</DL>

<P>
<A NAME="IDX5713"></A>
<A NAME="IDX5714"></A>
<DL>
<DT><span class="define">PREDICATE:</span> <B>instance_codes/2:</B>
<DD><A NAME="IDX5715"></A>


<P>
Retrieves a character string representation from an object identifier and vice-versa. 


<P>
<STRONG>Usage 1:</STRONG> <CODE>instance_codes(Instance, String)</CODE>

<UL>
<LI><EM>Description:</EM> Retrieves a <CODE>String</CODE> representation of given <CODE>Instance</CODE>.

<LI><EM>The following properties should hold at call time:</EM>

<CODE>Instance</CODE> is an unique term which identifies an object.
 (<CODE>objects_rt:instance_id/1</CODE>)

<CODE>String</CODE> is a free variable.
 (<CODE>term_typing:var/1</CODE>)
<LI><EM>The following properties should hold upon exit:</EM>

<CODE>String</CODE> is a string (a list of character codes).
 (<CODE>basic_props:string/1</CODE>)
</UL>

<P>
<STRONG>Usage 2:</STRONG> <CODE>instance_codes(Instance, String)</CODE>

<UL>
<LI><EM>Description:</EM> Reproduces an <CODE>Instance</CODE> from its <CODE>String</CODE> representation. Such an instance must be alive across the application: this predicate will fail whether the involved instance has been destroyed.

<LI><EM>The following properties should hold at call time:</EM>

<CODE>Instance</CODE> is a free variable.
 (<CODE>term_typing:var/1</CODE>)

<CODE>String</CODE> is a string (a list of character codes).
 (<CODE>basic_props:string/1</CODE>)
<LI><EM>The following properties should hold upon exit:</EM>

<CODE>Instance</CODE> is an unique term which identifies an object.
 (<CODE>objects_rt:instance_id/1</CODE>)
</UL>

</DL>

<P>
<A NAME="IDX5716"></A>
<A NAME="IDX5717"></A>
<DL>
<DT><span class="define">PREDICATE:</span> <B>destroy/1:</B>
<DD><A NAME="IDX5718"></A>


<P>
As well as instances are created, they must be destroyed when no longer needed in order to release system resources. 


<P>
Unfortunately, current O'Ciao implementation does not support automatic instance destruction, so user must manually call <EM>destroy/1</EM> in order to do so. 


<P>
The programmer <STRONG>must ensure</STRONG> that no other references to the involved object are left in memory when destroy/1 is called. If not, unexpected results may be obtained. 


<P>
<STRONG>Usage:</STRONG> <CODE>destroy(Instance)</CODE>

<UL>
<LI><EM>Description:</EM> Destroys the object identified by <CODE>Instance</CODE>.

<LI><EM>The following properties should hold at call time:</EM>

<CODE>Instance</CODE> is an unique term which identifies an object.
 (<CODE>objects_rt:instance_id/1</CODE>)
</UL>

</DL>

<P>
<A NAME="IDX5719"></A>
<A NAME="IDX5720"></A>
<DL>
<DT><span class="define">PREDICATE:</span> <B>use_class/1:</B>
<DD><A NAME="IDX5721"></A>


<P>
The behaviour of this predicate is identical to that provided by the declaration of the same name 
<A NAME="IDX5722"></A>
<CODE>use_class/1</CODE>. It allows user programs to dynamically load classes. Whether the given source is not a class it will perform a 
<A NAME="IDX5723"></A>
<CODE>use_module/1</CODE> predicate call.


<P>
<STRONG>Usage:</STRONG> <CODE>use_class(ClassSource)</CODE>

<UL>
<LI><EM>Description:</EM> Dynamically loads the given <CODE>ClassSource</CODE>

<LI><EM>The following properties should hold at call time:</EM>

<CODE>ClassSource</CODE> is a valid path to a prolog file containing a class declaration (without .pl extension).
 (<CODE>objects_rt:class_source/1</CODE>)
</UL>

</DL>

<P>
<A NAME="IDX5724"></A>
<A NAME="IDX5725"></A>
<DL>
<DT><span class="define">PROPERTY:</span> <B>constructor/1:</B>
<DD><A NAME="IDX5726"></A>


<P>
<STRONG>Usage:</STRONG> <CODE>constructor(Cons)</CODE>

<UL>
<LI><EM>Description:</EM> <CODE>Cons</CODE> is a term whose functor matches a class name.

</UL>

</DL>

<P>
<A NAME="IDX5727"></A>
<A NAME="IDX5728"></A>
<DL>
<DT><span class="define">PROPERTY:</span> <B>class_name/1:</B>
<DD><A NAME="IDX5729"></A>


<P>
<STRONG>Usage:</STRONG> <CODE>class_name(ClassName)</CODE>

<UL>
<LI><EM>Description:</EM> <CODE>ClassName</CODE> is an atom denoting a class.

</UL>

</DL>

<P>
<A NAME="IDX5730"></A>
<A NAME="IDX5731"></A>
<DL>
<DT><span class="define">PROPERTY:</span> <B>interface_name/1:</B>
<DD><A NAME="IDX5732"></A>


<P>
<STRONG>Usage:</STRONG> <CODE>interface_name(Interface)</CODE>

<UL>
<LI><EM>Description:</EM> <CODE>Interface</CODE> is an unique atom which identifies a public interface.

</UL>

</DL>

<P>
<A NAME="IDX5733"></A>
<A NAME="IDX5734"></A>
<DL>
<DT><span class="define">PROPERTY:</span> <B>instance_id/1:</B>
<DD><A NAME="IDX5735"></A>


<P>
<STRONG>Usage:</STRONG> <CODE>instance_id(ID)</CODE>

<UL>
<LI><EM>Description:</EM> <CODE>ID</CODE> is an unique term which identifies an object.

</UL>

</DL>

<P>
<A NAME="IDX5736"></A>
<A NAME="IDX5737"></A>
<DL>
<DT><span class="define">PROPERTY:</span> <B>class_source/1:</B>
<DD><A NAME="IDX5738"></A>


<P>
<STRONG>Usage:</STRONG> <CODE>class_source(Source)</CODE>

<UL>
<LI><EM>Description:</EM> <CODE>Source</CODE> is a valid path to a prolog file containing a class declaration (without .pl extension).

</UL>

</DL>

<P>
<A NAME="IDX5739"></A>
<A NAME="IDX5740"></A>
<DL>
<DT><span class="define">PROPERTY:</span> <B>interface_source/1:</B>
<DD><A NAME="IDX5741"></A>


<P>
<STRONG>Usage:</STRONG> <CODE>interface_source(Source)</CODE>

<UL>
<LI><EM>Description:</EM> <CODE>Source</CODE> is a valid path to a prolog file containing a class declaration or an interface declaration (without .pl extension).

</UL>

</DL>

<P>
<A NAME="IDX5742"></A>
<A NAME="IDX5743"></A>
<DL>
<DT><span class="define">PROPERTY:</span> <B>method_spec/1:</B>
<DD><A NAME="IDX5744"></A>


<P>
There is no difference between method or attribute specifications, and habitual predicate specifications. It is just a Functor/Arity term. 


<P>
<STRONG>Usage:</STRONG> <CODE>method_spec(Spec)</CODE>

<UL>
<LI><EM>Description:</EM> <CODE>Spec</CODE> is a method or attribute specification.

</UL>

</DL>

<P>
<A NAME="IDX5745"></A>
<A NAME="IDX5746"></A>
<DL>
<DT><span class="define">PROPERTY:</span> <B>virtual_method_spec/1:</B>
<DD><A NAME="IDX5747"></A>


<P>
<STRONG>Usage:</STRONG> <CODE>virtual_method_spec(Spec)</CODE>

<UL>
<LI><EM>Description:</EM> <CODE>Spec</CODE> is a method specification.

</UL>

</DL>



<H2><A NAME="SEC495" HREF="ciao_toc.html#TOC495">Known bugs and planned improvements (<CODE>objects_rt</CODE>)</A></H2>


<UL>

<LI>

Usage of objects from the <CODE>user</CODE> module does not work properly. It is better to use the <CODE>objects</CODE> package in a (proper) module.

<LI>

Not really a bug: when loading code which declares static instances from the toplevel shell, predicate 
<A NAME="IDX5748"></A>
<CODE>use_module/1</CODE>) will not work properly: those instances may be not correctly created, and predicates will fail whenever they are not supposed to do. This may be avoided by reloading again the involved module, but make sure it is modified and saved to disk before doing so. 
</UL>

<P><HR><P>
Go to the <A HREF="ciao_1.html">first</A>, <A HREF="ciao_116.html">previous</A>, <A HREF="ciao_118.html">next</A>, <A HREF="ciao_241.html">last</A> section, <A HREF="ciao_toc.html">table of contents</A>.
</BODY>
</HTML>