# Namespace lfun::

Description

  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()

Note

  Although these functions are called from outside the object they exist in, they will still be used even if they are declared `protected`. It is in fact recommended to declare them `protected`, since that will hinder them being used for other purposes.

See also

  ::

Variable symbol

  `mixed lfun::symbol`

Method create

  `void lfun:create(zero ... args)`

Description

  Object creation callback.

  This function is called right after lfun::__INIT().

  args are the arguments passed when the program was called.

Note

  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;
       protected void create(int foo)
       {
         local::foo = foo;
       }
     }

See also

  lfun::__INIT(), lfun::destroy()

Method destroy

  `void destroy(void|int reason)`

Description

  Object destruction callback.

  This function is called right before the object is destructed. That can happen either through a call to destruct(), when there are no more references to the object, or when the garbage collector discovers that it's part of a cyclic data structure that has become garbage.

Parameter `reason`

  A flag that tells why the object is destructed:

  `Object.DESTRUCT_EXPLICIT` | Destructed explicitly by destruct.
  `Object.DESTRUCT_NO_REFS` | Destructed due to running out of references.
  `Object.DESTRUCT_GC` | Destructed by the garbage collector.
  `Object.DESTRUCT_CLEANUP` | Destructed as part of the cleanup when the pike process exits. Occurs only if Pike has been compiled with the configure option `--with-cleanup-on-exit`. See note below.

Note

  Objects are normally not destructed when a process exits, so `destroy` functions aren't called then. Use atexit to get called when the process exits.

Note

  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.

  - If a cycle is resolved according to the rule above by ignoring a weaker reference, and there is another ambiguous cycle that would get resolved by ignoring the same reference, then the latter cycle will be resolved by ignoring that reference.

  - Weak references (e.g. set with 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 { protected void destroy() { if (!Super::this) error ("My parent has been destructed!\n"); } } Sub sub = Sub(); protected 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`.

Note

  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 will therefore be destroyed even if external references are added to them.

Note

  The garbage collector had completely random destruct order in versions prior to 7.2.

See also

  lfun::create(), destruct()