|
BasicClassDefinition
Syntax of defining a class
Featured IntroductionAn ECT class consists of a record definition and some function definitions. Instances of the class - objects - are actually instances of the record. The functions are also connected to the record in a way that will be discussed later. Those functions that are connected to a class are called methods. ECT classes are defined by modules. DefinitionHeaderTo make a module a class, at least the following two things have to be done:
-include_lib("ect/include/ect.hrl").
-class(animal).FieldsA class is similar to a record in the sense that it may have fields. They can be defined the following way: ?FIELDS({weight, color = red, field3 = initial_value, etc...}).MethodsA class module can contain arbitrary functions. To connect a function to the class, which is to make it a method, its name and arity should be enumerated with the use of the following macro: ?METHODS([method1/2, method2/2]). These methods has to be defined in the module of the class: method1(This, A) -> A. method2(This, A) -> A+1. The name of the first parameter can be anything, but it is good practice to call it This. This is because method calls always pass the object instance as the first parameter. Complete example-include_lib("ect/include/ect.hrl").
-class(animal).
?FIELDS({weight, color = red}).
?METHODS([method1/2, method2/2]).
method1(This, A) ->
A.
method2(This, A) ->
A+1.UsageAfter compiling the class, two files are produced: animal.beam and animal.class.hrl. The header file contains the record definition, and some additional information. The defined record has the name of the class, and contains the fields of the class. It also contains the fields of the superclasses if there is any, and an additional field, see ClassDataStructure for more details. To compile a module that uses the class, this generated header file must be included. -module(animal_test).
-include("animal.class.hrl").Field accessAccessing the fields of a class has the same syntax and semantics as using records. Differences only arise when using inheritance. For convenience, the record syntax is repeated here: InstantiationA = #animal{}or with some initialization A = #weight{field3 = 125}Getting the value of a single fieldA#animal.color Matching a pattern against a record#animal{weight = 40, color = C} = AUpdating fields of a classA2 = A#animal{color = blue, weight = 45}Nonstandard waysWhen tuple-patterns, element or setelement BIFS are used in conjunction with an object, special care needs to be taken, because the fields are shifted. Method callsTo call a method, first we need an instance. Then the following syntax can be used: A = #animal{},
X1 = {A}:method1(3),
X2 = {A}:method2(2).This syntax yields the following function calls: X1 = animal:method1(A, 3), X2 = animal:method2(A, 2) As you can see, the current object instance is always passed as the first parameter. Note that the actual module of the function calls is always decided at run time, based on the type of the object (A in this case). |