Subsections
Method Invocation
Instance Method Invocation
OQL allows one to call a instance method with or without parameters.
The method can be written in C++ or in OQL.
As in C++, method calls use a combination of the path expression operator and
the function call operator.
As in C++ or Java, methods can be overloaded: that
means that one can have differents methods with the same name and a
different signature or differents methods with the same name
and the same signature in a class hierarchy.
The choice of the method to invoke
is done at evaluation time not at compile time.
For instance let two
methods Person Person::f(in int, in int) and int Person::f(in float, in string),
the method to be invoked in the expression p->f(x, y) is decided
at evaluation time according to the true types of x and y:
p := first(select Person);
x := 1; y := 2;
p->f(x, y); // X::f(in int, in int) is invoked
p->f(x, y)->name; // this is valid because p->f(x, y) returns a Person
x := 1.3; y := "hello";
p->f(x, y); // X::f(in float, in string) is invoked
p->f(x, y)->name; // this is not valid because p->f(x, y) returns an integer
A major contribution of object orientation is the possibility of manipulating
polymorphic objects and thanks to the late binding mechanism
to carry out generic actions on the elements of these objects.
For instance, let the two
methods void Person::doit(in int)
and void Employee::doit(in int),
the method to be invoked in the expression p->doit(x) is decided
at evaluation time according to the true type of p:
p := new Person();
p->doit(1); // Person::doit(in int) is invoked
p := new Employee();
p->doit(1); // Employee::doit(in int) is invoked
To invoke a method, the following conditions must be realize:
- the object or oid on which the method is applied must be
an instance of a class, for instance X.
- the name of the invoked method, the number and the type of arguments
must be compatible with an existing method in the class X,
- the result type must match the expected type in the expression.
For instance, let the methods int compute(in int, int float) and
int compute(in int, in float, in int[], out string)
in the class X.
To invoke the first method on an instance of X, one needs to
apply the method compute to an instance of X
with one integer and one float, for instance:
x := new X();
x.compute(1, 2.3);
x.compute(a := fact(10), float(fib(10)));
To invoke the second method on an instance of X, one needs to
apply the method compute to an instance of X
with an integer, a float, an ordered collection of integer and a reference
to a variable, for instance:
x.compute(1, 23.4, list(1, 2, 3, 4), &a);
The following table shows the mapping (which defines the compatibility)
between the ODL and the OQL types.
ODL/OQL Mapping |
ODL Type |
OQL Type |
in int16 |
integer |
out int16 |
identifier |
inout int16 |
identifier initialized to an integer |
in int32 |
integer |
out int32 |
identifier |
inout int32 |
identifier initialized to an integer |
in int64 |
integer |
out int64 |
identifier |
inout int64 |
identifier initialized to an integer |
in byte |
char |
out byte |
identifier |
inout byte |
identifier initialized to a char |
in char |
char |
out char |
identifier |
inout char |
identifier initialized to a char |
in string |
string |
out string |
identifier |
inout string |
identifier initialized to a string |
in float |
float |
out float |
identifier |
inout float |
identifier initialized to a float |
in oid |
oid |
out oid |
identifier |
inout oid |
identifier initialized to a oid |
in object * |
oid of any class |
out object * |
identifier |
inout object * |
identifier initialized to an oid of any class |
in X * (X denotes a class instance) |
oid of class X |
out X * (X denotes a class instance) |
identifier |
inout X * (X denotes a class instance) |
identifier initialized to a oid of class X |
in X *[] (X denotes a class instance) |
ordered collection of oid of class X |
out X *[] (X denotes a class instance) |
identifier |
inout X *[] (X denotes a class instance) |
identifier initialized to an ordered collection of oid of class X |
in X[] (X denotes any ODL type) |
ordered collection of atoms bound to X |
out X[] (X denotes any ODL type) |
identifier |
inout X[] (X denotes any ODL type) |
identifier initialized to an ordered collection of atoms bound to X |
Note: contrary to the ODMG 3 specifications, one currently needs
to use parenthesis to invoke a method even if the method has no arguments.
General Information |
Operators |
. |
|
-> |
Syntaxes |
expr . expr (expr_list) |
|
expr -> expr (expr_list) |
Type |
n-ary |
Operand Types |
first operand: oid or object,
second operand: identifier, other operands: any type |
Result Type |
type of the atom returned by the method call |
Functions |
invokes the method denoted by the second operand applied to the
object denoted by the first operand, using the other operands as arguments. |
|
The first operand must denote an EYEDB instance (object or literal) of
an agregat including the method whose name is the second operand.
The number of arguments and the type of arguments must match one of
the methods included in the class of the object denoted by the first operand. |
Note |
these two operators are identical |
Expression Examples |
expression |
result |
comments |
p->getOid() |
the value of the oid of object denoted by
p |
as getOid() is a native method of the class
object, each object can call
this method |
img->compute(1, 2.3) |
the value returned by the method call |
the first operand must denote an EYEDB instance (object or literal) of
an agregat including the method whose name is compute |
first(select Person.name = "wayne").getSpouse() |
the value returned by the method call |
|
Class Method Invocation
OQL allows one to call a class method with or without parameters.
The method can be written in C++ or in OQL.
As in C++, method calls use a combination of the scope operator and
the function call operator.
To invoke a class method, the following conditions must be realize:
- the name of the invoked method, the number and the type of arguments
must be compatible with an existing method in the class X,
- the result type must match the expected type in the expression.
The overloading and the late binding mechanisms are the same as for
the instance method invocations.
General Information |
Operator |
:: |
Syntaxe |
identifier::identifier(expr_list) |
Type |
n-ary |
Operand Types |
first operand: identifier,
second operand: identifier,
other operands: any type |
Result Type |
type of the atom returned by the method call |
Functions |
invokes the class method denoted by the second operand applied to the
class denoted by the first operand, using the other operands as arguments. |
|
The first operand must denote an EYEDB class of
an agregat including the class method whose name is the second operand.
The number of arguments and the type of arguments must match one of
the class methods included in the class denoted by the first operand. |
Expression Examples |
expression |
result |
comments |
EyeDB::getVersion() |
2.8.7 |
getVersion() is a native static method of the class EyeDB |
Person::checkName("johnny") |
the value returned by the method call |
the class method checkName must exist in the class Person
and must take one and only one input string argument. |
EyeDB manual