m
Move page script moved page Object-oriented programming to WoW:Object-oriented programming without leaving a redirect
m (catfix) |
m (Move page script moved page Object-oriented programming to WoW:Object-oriented programming without leaving a redirect) |
||
| (5 intermediate revisions by 5 users not shown) | |||
| Line 1: | Line 1: | ||
{{ | {{wowlua}} | ||
Object Oriented Programming (OOP) is a relatively new concept (compared to procedural programing) which allows code to become "objects." These objects can be duplicated, extended, and in some languages, be converted between relatives. Object Oriented Programming also allows for programmers to maintain organization in their programs. This is especially vital in WoW addons, as all addons share the same [[execution environment]] and thus can conflict if poorly organized. | Object Oriented Programming (OOP) is a relatively new concept (compared to procedural programing) which allows code to become "objects." These objects can be duplicated, extended, and in some languages, be converted between relatives. Object Oriented Programming also allows for programmers to maintain organization in their programs. This is especially vital in WoW addons, as all addons share the same [[execution environment]] and thus can conflict if poorly organized. | ||
| Line 20: | Line 21: | ||
=== Lua Namespaces === | === Lua Namespaces === | ||
In [[Lua]], namespaces don't directly exist. However, Lua programmers typically take advantage of several key, and unique, features which are available in the language to provide | In [[Lua]], namespaces don't directly exist. However, Lua programmers typically take advantage of several key, and unique, features which are available in the language to provide an indirect mechanism which can be considered setting up a namespace. Some other programmers, unfamiliar with languages that don't allow for the creation of namespaces, may confuse these with classes, but the major difference is that only one instance of a namespace ever exists, while there can be many separate instances of a class. | ||
In Lua, a function is a variable. As such, it should be noted that a reference to a function can be used wherever a variable is used. The implications of this is that functions can be stored inside tables. Furthermore, in WoW, all addons share the same [[execution environment]], therefore it is vital that some form of [[Lua_Scope|scope limitation]] is used so common variable names do not cause addon conflicts. Namespaces are one such method to organize code, thus limiting conflicts. | In Lua, a function is a variable. As such, it should be noted that a reference to a function can be used wherever a variable is used. The implications of this is that functions can be stored inside tables. Furthermore, in WoW, all addons share the same [[execution environment]], therefore it is vital that some form of [[Lua_Scope|scope limitation]] is used so common variable names do not cause addon conflicts. Namespaces are one such method to organize code, thus limiting conflicts. | ||
| Line 38: | Line 39: | ||
=== Namespace Use === | === Namespace Use === | ||
Many Lua programmers consider the use of Lua namespaces as an indicator of a good understanding of the language. This is because it is very organized and requires a good understanding of several language features. Encapsulating your addon within one or a few namespaces can result in allowing your addon to use a minimal number of global variables, thus minimizing its global namespace pollution. | Many Lua programmers consider the use of Lua namespaces as an indicator of a good understanding of the language. This is because it is very organized and requires a good understanding of several language features. Encapsulating your addon within one or a few namespaces can result in allowing your addon to use a minimal number of global variables, thus minimizing its global namespace pollution. | ||
Many addons authors create a single namespace which encapsulates all its code. This limits the addon's exposure without limiting functionality. Instead of creating 10 global functions, for example, the addon instead has a single namespace and 10 functions which are accessible within that namespace. The following code segment provides a bad example which unnecessarily pollutes the global namespace, and then provides a functionally equivalent example, which is far more organized. It creates two functions and two variables in the namespace: | Many addons authors create a single namespace which encapsulates all its code. This limits the addon's exposure without limiting functionality. Instead of creating 10 global functions, for example, the addon instead has a single namespace and 10 functions which are accessible within that namespace. The following code segment provides a bad example which unnecessarily pollutes the global namespace, and then provides a functionally equivalent example, which is far more organized. It creates two functions and two variables in the namespace: | ||
| Line 68: | Line 69: | ||
== Classes == | == Classes == | ||
Classes are very similar to namespaces, and implemented almost identically in Lua. Many programmers consider classes to be the fundamental concept of Object Oriented Programming, and the building block upon which other concepts can be created. They, like namespaces, are containers, but containers that can be duplicated. You can have many instances of a class, even though it's only declared once. Take the following C++ example: | Classes are very similar to namespaces, and are implemented almost identically in Lua. Many programmers consider classes to be the fundamental concept of Object Oriented Programming, and the building block upon which other concepts can be created. They, like namespaces, are containers, but containers that can be duplicated. You can have many instances of a class, even though it's only declared once. Take the following C++ example: | ||
class Foo | class Foo | ||
| Line 109: | Line 110: | ||
==== Member Variables ==== | ==== Member Variables ==== | ||
A "member variable" is a term used to identify a variable that exists in a class. Member variables are not explicitly declared in Lua, but rather they are typically created during construction (when the class is instantiated). | A "member variable" is a term used to identify a variable that exists in a class. Member variables are not explicitly declared in Lua, but rather they are typically created during construction (when the class is instantiated). | ||
function Character:new() | function Character:new() | ||
| Line 123: | Line 124: | ||
==== Member Functions ==== | ==== Member Functions ==== | ||
Like member variables, member functions are simply functions that are contained within the class. Even more interestingly, as functions are variables in Lua, functions can differ between classes. Since tables can store functions, adjusting the value of one of those functions can change the operation for that one instance, but leave the other instances identical. Sometimes this is preferred. However, sometimes, we want a change to propagate to all classes. | Like member variables, member functions are simply functions that are contained within the class. Even more interestingly, as functions are variables in Lua, functions can differ between classes. Since tables can store functions, adjusting the value of one of those functions can change the operation for that one instance, but leave the other instances identical. Sometimes this is preferred. However, sometimes, we want a change to propagate to all classes. | ||
===== Explicit Function Creation ===== | ===== Explicit Function Creation ===== | ||
One form of creating member functions is shown in the following example. Like member variables, these functions can be created during construction, | One form of creating member functions is shown in the following example. Like member variables, these functions can be created during construction, and thus it can be quickly seen how each class has its own instance of a function, as well, thus they can be changed in the future if desired: | ||
function Character:new() | function Character:new() | ||
| Line 163: | Line 164: | ||
end | end | ||
Note the slight difference: We use a colon instead of a period here. This is typically used for non-static functions (functions which rely upon the state of the class, or the variables inside the instance of the class, to determine their operation). This is needed because we need to know the variable "race" inside our instance. This determines whether the function returns true or false. The use of this colon states that, when this function is called, a [[ | Note the slight difference: We use a colon instead of a period here. This is typically used for non-static functions (functions which rely upon the state of the class, or the variables inside the instance of the class, to determine their operation). This is needed because we need to know the variable "race" inside our instance. This determines whether the function returns true or false. The use of this colon states that, when this function is called, a [[Lua Scope#Function-local Variables|function-local variable]] will be created. The variable will be named "self" and is a reference to the instance of the class. Thus, we can use the variable "self.class" to determine the class of that one particular character. The Lua reference manual states the following[http://www.lua.org/manual/5.1/manual.html]: | ||
:The colon syntax is used for defining methods, that is, functions that have an implicit extra parameter self. Thus, | :The colon syntax is used for defining methods, that is, functions that have an implicit extra parameter self. Thus, the statement | ||
::function t.a.b.c:f (params) body end | ::function t.a.b.c:f (params) body end | ||
:is syntactic sugar for | :is syntactic sugar for | ||