8. LFUN |
Namespace lfun:: |
Callback functions used to overload various builtin functions.
The functions can be grouped into a few sets:
Object initialization and destruction.
__INIT() , create() , destroy()
Unary operator overloading.
`~() , `!() , _values() , cast() , _sizeof() , _indices() , __hash()
Binary asymmetric operator overloading.
`+() , ``+() , `-() , ``-() , `&() , ``&() , `|() , ``|() , `^() , ``^() , `<<() , ``<<() , `>>() , ``>>() , `*() , ``*() , `/() , ``/() , `%() , ``%()
Binary symmetric operator overloading.
The optimizer will make assumptions about the relations between these functions.
`==() , _equal() , `<() , `>()
Other binary operator overloading.
`[]() , `[]=() , `->() , `->=() , `+=() , `()()
Overloading of other builtin functions.
_is_type() , _sprintf() , _m_delete() , _get_iterator() , _search()
Although these functions are called from outside the object
they exist in, they will still be used even if they are
declared static
. It is in fact recommended to declare
them static
, since that will hinder them being used
for other purposes.
::
mixed lfun::_sqrt()
Called by sqrt when the square root of an object is requested.
_sqrt is not a real lfun, so it must not be defined as static.
predef::sqrt()
mixed lfun::_random()
Called by random . Typical uses is when the object implements a ADT, then a call to this lfun should return a random member of the ADT or range implied by the ADT.
predef::random()
void lfun::__INIT()
Inherit and variable initialization.
This function is generated automatically by the compiler. It's called just before lfun::create() when an object is instantiated.
It first calls any __INIT
functions in inherited classes
(regardless of modifiers on the inherits). It then executes all
the variable initialization expressions in this class, in the
order they occur.
This function can not be overloaded or blocked from executing.
lfun::create()
void lfun::(zero ... args)
Object creation callback.
This function is called right after lfun::__INIT() .
args are the arguments passed when the program was called.
In Pike 7.2 and later this function can be created implicitly by the compiler using the new syntax:
class Foo(int foo) {
int bar;
}
In the above case an implicit lfun::create() is created, and it's equvivalent to:
class Foo {
int foo;
int bar;
static void create(int foo)
{
local::foo = foo;
}
}
lfun::__INIT() , lfun::destroy()
void lfun::destroy()
Object destruction callback.
This function is called by predef::destruct() right before it zeroes all the object variables and destroys the object.
Note that it's also called on implicit destruct, i.e. when there are no more references to the object, or when the garbage collector decides to destruct it.
Regarding destruction order during garbage collection:
If an object is destructed by the garbage collector, it's part of
a reference cycle with other things but with no external
references. If there are other objects with destroy
functions in the same cycle, it becomes a problem which to call
first.
E.g. if this object has a variable with another object which (directly or indirectly) points back to this one, you might find that the other object already has been destructed and the variable thus contains zero.
The garbage collector tries to minimize such problems by defining an order as far as possible:
If an object A contains an lfun::destroy and an object B does not, then A is destructed before B.
If A references B single way, then A is destructed before B.
If A and B are in a cycle, and there is a reference somewhere from B to A that is weaker than any reference from A to B, then A is destructed before B.
Weak references (e.g. set with predef::set_weak_flag() ) are considered weaker than normal references, and both are considered weaker than strong references.
Strong references are those from objects to the objects of their lexically surrounding classes. There can never be a cycle consisting only of strong references. (This means the gc never destructs a parent object before all children have been destructed.)
An example with well defined destruct order due to strong references:
class Super {
class Sub {
static void destroy() {
if (!Super::this)
error ("My parent has been destructed!\n");
}
}
Sub sub = Sub();
static void destroy() {
if (!sub)
werror ("sub already destructed.\n");
}
}
The garbage collector ensures that these objects are destructed in
an order so that werror
in Super
is called and not
error
in Sub
.
When the garbage collector calls lfun::destroy , all accessible
non-objects and objects without destroy
functions are
still intact. They are not freed if the destroy
function
adds external references to them. However, all objects with
lfun::destroy in the cycle are already scheduled for
destruction and are thus be destroyed even if external references
are added to them.
The garbage collector had completely random destruct order in versions prior to 7.2.
lfun::create() , predef::destruct()
mixed lfun::`+(zero arg, zero ... rest)
Left side addition/concatenation callback.
This is used by predef::`+ . It's called with any arguments that follow this object in the argument list of the call to predef::`+ . The returned value should be a new instance that represents the addition/concatenation between this object and the arguments in the order they are given.
It's assumed that this function is side-effect free.
lfun::``+() , lfun::`+=() , predef::`+()
this_program lfun::`+=(zero arg, zero ... rest)
Destructive addition/concatenation callback.
This is used by predef::`+ . It's called with any arguments that follow this object in the argument list of the call to predef::`+ . It should update this object to represent the addition/concatenation between it and the arguments in the order they are given. It should always return this object.
This function should only be implemented if lfun::`+() also is. It should only work as a more optimized alternative to that one, for the case when it's safe to change the object destructively and use it directly as the result.
This function is not an lfun for the +=
operator. It's
only whether or not it's safe to do a destructive change that
decides if this function or lfun::`+() is called; both the
+
operator and the +=
operator can call either
one.
lfun::`+() , predef::`+()
mixed lfun::``+(zero arg, zero ... rest)
Right side addition/concatenation callback.
This is used by predef::`+ . It's called with any arguments that precedes this object in the argument list of the call to predef::`+ . The returned value should be a new instance that represents the addition/concatenation between the arguments in the order they are given and this object.
It's assumed that this function is side-effect free.
lfun::`+() , predef::`+()
mixed lfun::`-(void|zero arg)
Negation and left side subtraction/set difference callback.
This is used by predef::`- . When called without an argument the result should be a new instance that represents the negation of this object, otherwise the result should be a new instance that represents the difference between this object and arg .
It's assumed that this function is side-effect free.
lfun::``-() , predef::`-()
mixed lfun::``-(zero arg)
Right side subtraction/set difference callback.
This is used by predef::`- . The result should be a new instance that represents the difference between arg and this object.
It's assumed that this function is side-effect free.
lfun::`-() , predef::`-()
mixed lfun::`&(zero ... args)
Left side bitwise and/intersection callback.
It's assumed that this function is side-effect free.
lfun::``&() , predef::`&()
mixed lfun::``&(zero ... args)
Right side bitwise and/intersection callback.
It's assumed that this function is side-effect free.
lfun::`&() , predef::`&()
mixed lfun::`|(zero ... args)
Left side bitwise or/union callback.
It's assumed that this function is side-effect free.
lfun::``|() , predef::`|()
mixed lfun::``|(zero ... args)
Right side bitwise or/union callback.
It's assumed that this function is side-effect free.
lfun::`|() , predef::`|()
mixed lfun::`^(zero ... args)
Left side exclusive or callback.
It's assumed that this function is side-effect free.
lfun::``^() , predef::`^()
mixed lfun::``^(zero ... args)
Right side exclusive or callback.
It's assumed that this function is side-effect free.
lfun::`^() , predef::`^()
mixed lfun::`<<(zero arg)
Left side left shift callback.
It's assumed that this function is side-effect free.
lfun::``<<() , predef::`<<()
mixed lfun::``<<(zero arg)
Right side left shift callback.
It's assumed that this function is side-effect free.
lfun::`<<() , predef::`<<()
mixed lfun::`>>(zero arg)
Left side right shift callback.
It's assumed that this function is side-effect free.
lfun::``>>() , predef::`>>()
mixed lfun::``>>(zero arg)
Right side right shift callback.
It's assumed that this function is side-effect free.
lfun::`>>() , predef::`>>()
mixed lfun::`*(zero ... args)
Left side multiplication/repetition/implosion callback.
It's assumed that this function is side-effect free.
lfun::``*() , predef::`*()
mixed lfun::``*(zero ... args)
Right side multiplication/repetition/implosion callback.
It's assumed that this function is side-effect free.
lfun::`*() , predef::`*()
mixed lfun::`/(zero ... args)
Left side division/split callback.
It's assumed that this function is side-effect free.
lfun::``/() , predef::`/()
mixed lfun::``/(zero ... args)
Right side division/split callback.
It's assumed that this function is side-effect free.
lfun::`/() , predef::`/()
mixed lfun::`%(zero ... args)
Left side modulo callback.
It's assumed that this function is side-effect free.
lfun::``%() , predef::`%()
mixed lfun::``%(zero ... args)
Right side modulo callback.
It's assumed that this function is side-effect free.
lfun::`%() , predef::`%()
int lfun::`!()
Logical not callback.
Returns non-zero if the object should be evaluated as false,
and 0
(zero) otherwise.
It's assumed that this function is side-effect free.
predef::`!()
mixed lfun::`~()
Complement/inversion callback.
It's assumed that this function is side-effect free.
predef::`~()
int(0..1) lfun::`==(mixed arg)
Equality test callback.
If this is implemented it might be necessary to implement lfun::__hash too. Otherwise mappings might hold several objects as indices which are duplicates according to this function. Various other functions that use hashing also might not work correctly, e.g. predef::Array.uniq .
It's assumed that this function is side-effect free.
predef::`==() , lfun::__hash
int(0..1) lfun::`<(mixed arg)
Less than test callback.
It's assumed that this function is side-effect free.
predef::`<()
int(0..1) lfun::`>(mixed arg)
Greater than test callback.
It's assumed that this function is side-effect free.
predef::`>()
int lfun::__hash()
Hashing callback.
This function gets called by various mapping operations when the object is used as index in a mapping. It should return an integer that corresponds to the object in such a way that all values which lfun::`== considers equal to the object gets the same hash value.
The function predef::hash does not return hash values that are compatible with this one.
It's assumed that this function is side-effect free.
lfun::`==
mixed lfun::cast(string requested_type)
Value cast callback.
Type to cast to.
Expected to return the object value-casted (converted) to the type described by requested_type .
The argument is currently a string with the name of the type, but might in the future be a value of the type type.
Currently casting between object types is a noop.
If the returned value is not deemed to be of the requested type a runtime error may be thrown.
It's assumed that this function is side-effect free.
mixed lfun::`[](zero arg1, zero|void arg2)
Index/subrange callback.
It's assumed that this function is side-effect free.
predef::`[]()
mixed lfun::`[]=(zero arg1, zero arg2)
Index assignment callback.
predef::`[]=() , lfun::`->=()
mixed lfun::`->(string arg)
Arrow index callback.
It's assumed that this function is side-effect free.
predef::`->()
mixed lfun::`->=(string arg1, zero arg2)
Arrow index assignment callback.
predef::`->=() , lfun::`[]=()
int lfun::_sizeof()
Size query callback.
Called by predef::sizeof() to determine the number of elements in an object. If this function is not present, the number of public symbols in the object will be returned.
Expected to return the number of valid indices in the object.
It's assumed that this function is side-effect free.
predef::sizeof()
array lfun::_indices()
List indices callback.
Expected to return an array with the valid indices in the object.
It's assumed that this function is side-effect free.
predef::indices() , lfun::_values()
array lfun::_values()
List values callback.
Expected to return an array with the values corresponding to the indices returned by lfun::_indices() .
It's assumed that this function is side-effect free.
predef::values() , lfun::_indices()
mixed lfun::`()(zero ... args)
Apply callback.
predef::`()
int(0..1) lfun::_is_type(string basic_type)
Type comparison callback.
Called by the cast operator to determine if an object simulates a basic type.
One of:
|
The following five shouldn't occurr, but are here for completeness:
|
Expected to return 1
if the object is to be regarded as a
simulation of the type specified by basic_type .
The argument is currently a string with the name of the type, but might in the future be a value of the type type.
It's assumed that this function is side-effect free.
string lfun::_sprintf(int conversion_type, mapping(string:int)|void params)
Sprintf callback.
This method is called by predef::sprintf() to print objects. If it is
not present, printing of the object will not be supported for any
conversion-type except for the %O-conversion-type, which
will output "object"
.
One of:
|
Conversion parameters. The following parameters may be supplied:
|
Is expected to return a string describing the object formatted according to conversion_type .
_sprintf() is currently not called for the following conversion-types:
|
This function might be called at odd times, e.g. before
lfun::create has been called or when an error has occurred.
The reason is typically that it gets called when a backtrace is
being formatted to report an error. It should therefore be very
robust and not make any assumptions about its own internal
state, at least not when conversion_type is 'O'
.
It's assumed that this function is side-effect free.
predef::sprintf()
int lfun::_equal(mixed arg)
Recursive equality callback.
It's assumed that this function is side-effect free.
predef::equal() , lfun::`==()
mixed lfun::_m_delete(mixed arg)
Delete index callback.
predef::m_delete()
predef::Iterator lfun::_get_iterator()
Iterator creation callback.
The returned predef::Iterator instance works as a cursor that references a specific item contained (in some arbitrary sense) in this one.
It's assumed that this function is side-effect free.
predef::Iterator , predef::get_iterator , predef::foreach()
mixed lfun::_search(mixed needle, mixed|void start)
Search callback.
predef::search()
Namespace :: |
Symbols implicitly inherited from the virtual base class.
These symbols exist mainly to simplify implementation of the corresponding lfuns.
lfun::
mixed ::`->(string index)
Builtin arrow operator.
This function indexes the current object with the string index . This is useful when the arrow operator has been overloaded.
::`->=()
void ::`->=(string index, mixed value)
Builtin arrow set operator.
This function indexes the current object with the string index , and sets it to value . This is useful when the arrow set operator has been overloaded.
::`->()
mixed ::_indices()
Builtin function to list the identifiers of an object. This is useful when lfun::_indices has been overloaded.
::_values, ::`->
mixed ::_values()
Builtin function to list the values of the identifiers of an object. This is useful when lfun::_values has been overloaded.
::_indices, ::`->