156 lines
7.7 KiB
HTML
Executable File
156 lines
7.7 KiB
HTML
Executable File
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
|
|
<head>
|
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
|
<title>LOOP: Basic Concepts</title>
|
|
<style type="text/css" media="all"><!--
|
|
@import "../loop.css";
|
|
@import "../layout1.css";
|
|
--></style>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="Header">Class Models for Lua</div>
|
|
<div id="Logo"><img alt="small (1K)" src="../small.gif" height="70"></div>
|
|
|
|
<div id="Menu">
|
|
<div class="outside"><div class="inside"><ul>
|
|
<li><a href="../index.html", title="">Home</a></li>
|
|
<li><a href="../release/index.html", title="Installation">Install</a></li>
|
|
<li><a href="index.html", title="User Manual">Manual</a>
|
|
<div class="outside"><div class="inside"><ul>
|
|
<li><a href="intro.html", title="Introduction">Intro</a></li>
|
|
<li><strong>Basics</strong></li>
|
|
<li><a href="models.html", title="Class Models">Models</a></li>
|
|
<li><a href="classops.html", title="Class Features">Classes</a></li>
|
|
<li><a href="components.html", title="Component Models">Comps</a></li>
|
|
</ul></div></div>
|
|
</li>
|
|
<li><a href="../library/index.html", title="Class Library">Library</a></li>
|
|
<li><a href="../contact.html", title="Contact People">Contact</a></li>
|
|
<li><a href="http://luaforge.net/projects/oil/", title="Project at LuaForge">LuaForge</a></li>
|
|
</ul></div></div>
|
|
|
|
</div>
|
|
|
|
<div class="content">
|
|
<h1>Basic Concepts</h1>
|
|
|
|
<p>All LOOP class models present a set of common functionalities, as is presented in this section. For instance, all models are presented as sub-packages of the LOOP package. Therefore, to require a particular model you should use the following command:</p>
|
|
|
|
<pre>
|
|
-- use the LOOP model named 'simple'
|
|
-- for classes with simple inheritance
|
|
local oo = require "loop.simple"
|
|
</pre>
|
|
|
|
<h2><a name="classes">Declaring Classes</a></h2>
|
|
|
|
<p>All object models currently provided by LOOP are based on classes to implement behavioral sharing. Therefore, to create a LOOP object you must first define a class for it using the operation <code>class(definition)</code>. This operation receives a table that must be used as the class. Generally, a LOOP class can be seen as the meta-table of all objects of that class, <i>i.e.</i> it contains the meta-methods that defines the behavior of its instances. Since object classes usually are also used to define common features provided by all instances, every LOOP class has a default implementation of the <code>__index</code> meta-method that retrieves fields from the class. This way, every field defined by the class is shared by all its instances. For example, suppose the following class definition.</p>
|
|
|
|
<pre>
|
|
-- model with no inheritance
|
|
local oo = require "loop.base"
|
|
|
|
local Date = oo.class{
|
|
-- default field values
|
|
day = 1,
|
|
month = 1,
|
|
year = 1900,
|
|
}
|
|
function Date:addyears(years)
|
|
self.year = self.year + years
|
|
end
|
|
function Date:__tostring()
|
|
return string.format("%d/%d/%d",
|
|
self.month,
|
|
self.day,
|
|
self.year)
|
|
end
|
|
</pre>
|
|
|
|
<p>The class <code>Date</code> defines the fields <code>day</code>, <code>month</code>, <code>year</code> with default values and provides the implementation of the method <code>addyear</code> and the <code>__tostring</code> meta-method that is used by the tostring function of Lua base library. Therefore, all instances of class <code>Date</code> will share this behavior.</p>
|
|
|
|
<h2><a name="objects">Creating Objects</a></h2>
|
|
|
|
<p>Suppose the following code that creates an instance of class <code>Date</code> and uses it to find out the next birthday of a person.</p>
|
|
|
|
<pre>
|
|
function input(message, validator)
|
|
print(message)
|
|
return assert(validator(io.read()))
|
|
end
|
|
|
|
local day = input("Enter the day of your birth" , tonumber)
|
|
local month = input("Enter the month of your birth", tonumber)
|
|
local year = input("Enter the year of your birth" , tonumber)
|
|
local age = input("Enter your age" , tonumber)
|
|
|
|
-- new Date instance that overrides default values
|
|
local birthday = Date {
|
|
day = day,
|
|
month = month,
|
|
year = year,
|
|
}
|
|
birthday:addyears(age + 1)
|
|
print("Your next birthday will be on", birthday)
|
|
</pre>
|
|
|
|
<p>All classes of LOOP models can be instantiated like in the example above that is using the class as a constructor that receives the values used to create an instance and returns it. Alternatively, instances can be created by the operation <code>new</code> that receives as parameters the class and the values used to create the instance.</p>
|
|
|
|
<h2><a name="__init">Initializing Objects</a></h2>
|
|
|
|
<p>The default way instances are created is using the first argument informed as the object that must become an instance of the class. That is why the above example passes a table for the class in order to create the instance. However, this behavior can be redefined by the definition of the <code>__init</code> field on the class. This field works like a meta-method that is used to create instances of a class. The function stored at field <code>__init</code> receives the class and all the values provided to the class constructor. For example, suppose that we want to change the class <code>Date</code> so it can be instantiated from a tripe of numbers instead of a table containing possible replacements of default attribute values, then we can use the code provided below.</p>
|
|
|
|
<pre>
|
|
function Date:__init(month, day, year)
|
|
-- self is the class
|
|
return oo.rawnew(self, {
|
|
day = day,
|
|
month = month,
|
|
year = year,
|
|
})
|
|
end
|
|
</pre>
|
|
|
|
<p>The <code>rawnew</code> function is used to forcefully turn a table into an instance of a class without calling the <code>__init</code> function. The <code>rawnew</code> function can be roughly comparable to the setmetatable function of Lua with switched parameters (actually that is its implementation in most LOOP models). The main purpose of the <code>__init</code> function is to initialize a table so it can be turned into an instance of a class. This way the class may define may different semantics for the constructor. For example, consider the two following types of constructors.</p>
|
|
|
|
<pre>
|
|
function Constructed:__init(...)
|
|
-- creates and initialize a brand
|
|
-- new instance with the values of
|
|
-- provided parameters
|
|
return oo.rawnew(self, { ... })
|
|
end
|
|
|
|
function Mutant:__init(object)
|
|
object = object or {}
|
|
-- optionally checks if the object
|
|
-- presents the expected state
|
|
-- and turns it into an instance
|
|
return oo.rawnew(self, object)
|
|
end
|
|
</pre>
|
|
|
|
<p>When <code>Constructed</code> constructor is called, it always return a brand new instance, so it is not possible to properly make an existing table an instance of <code>Constructed</code> (unless using the <code>rawnew</code> function). On the other hand, the constructor of <code>Mutant</code> class can be used to initialize the table properly prior to the actual instantiation performed by <code>rawnew</code>.</p>
|
|
|
|
<h2><a name="introsp">Introspection Mechanisms</a></h2>
|
|
|
|
<p>Finally, all LOOP models provide introspection operations like <code>classof(object)</code>, <code>isclass(table)</code>, <code>instanceof(object, class)</code>, <code>memberof(class, name)</code> and <code>members(class)</code> for retrieving the LOOP class of an object, check whether a table is a class of the LOOP model, check whether an object is an instance of a given class, get the value of a member defined in a class, and iterating through all class members, respectively.</p>
|
|
|
|
</div>
|
|
|
|
<div class="content">
|
|
<p><small><strong>Copyright (C) 2004-2008 Tecgraf, PUC-Rio</strong></small></p>
|
|
<small>This project is currently being maintained by <a href="http://www.tecgraf.puc-rio.br">Tecgraf</a> at <a href="http://www.puc-rio.br">PUC-Rio</a>.</small>
|
|
</div>
|
|
|
|
|
|
|
|
</body>
|
|
|
|
</html>
|