Anvil | Smiths Smiths | Register Register | Login Login |
Search:
Show links Show tools Show tree | Previous document Next document | njet.org > Anvil > Documentation > Language reference > Classes > Class customization

Class customization

Behaviour of anvil script classes can be changed by declaring specially named methods that behave as an callbacks for different operations.

Callback methods
Method name Parameters Description
Standard methods. These map into methods found in anvil.lang.object
copy -

Copy method perfoms shallow copying of object. Default implementation works by recursive calling copy for each item inside object. While it works well most of cases, it cannot handle cycles in object graphs. They will cause stack overdflow.

Copy is also called on copyof expr expression.

clone -

Clone method perfoms shallow copying of object. This means that object should be cloned, but not its content. For instance, list container should copy the list, but use the same objects for lists values. Default implementation does this.

Clone is also called on cloneof expr expression.

toBoolean -

Method is called when object is placed on expression requiring boolean value, such as, if statement. Default implementation return always true.

toBoolean is also called on (boolean)expr expression.

toString -

Method should return informative string represention of an object. It is called, for instance, when object is printed. Default recursive implementation is vulnerable to stack overflows and therefore it should be overridden if cycles are possible.

toString is also called on (string)expr expression.

sizeOf -

Sizeof should return logical size of an object. Default implementation returns 0.

sizeOf is also called on sizeof expr expression.

hashCode -

Returns a hash code value for the object. This method is supported for the benefit of containers such as arrays. The general contract of hashCode is:

  • Whenever it is invoked on the same object more than once during an execution, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of arrays.
As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. This is implemented by returning the memoery address of an object.

equals (anotherObject)

Indicates whether some other object is "equal to" this one.

The equals method implements an equivalence relation:

  • It is reflexive: for any reference value x, x.equals(x) should return true.
  • It is symmetric: for any reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive: for any reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent: for any reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the object is modified. For any non-null reference value x, x.equals(null) should return false.

The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any reference values x and y, this method returns true if and only if x and y refer to the same object (x==y has the value true).

Default implementation compares object addresses

Equals is also called on following expressions:

expr == expr
Equals, type coersion might occur.
expr != expr
Not equal, type coersion might occur.
expr === expr
Not equal, exact.
expr !== expr
Not equal, exact

compareTo (anotherObject)

Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.

The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must throw an exception iff y.compareTo(x) throws an exception.)

The implementor must also ensure that the relation is transitive: (x.compareTo(y)>0 && y.compareTo(z)>0) implies x.compareTo(z)>0.

Finally, the implementer must ensure that x.compareTo(y)==0 implies that sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z.

It is strongly recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact. The recommended language is "Note: this class has a natural ordering that is inconsistent with equals."

compareTo is also called on following expressions:

expr < expr
Less than
expr > expr
Greater than
expr <= expr
Less than, or equal to
expr >= expr
Greater than, or equal to
expr <=> expr
Comparison with type coersions, returns whatever compareTo returns.
expr <==> expr
Exact comparison, returns whatever compareTo returns.

Attribute emulation methods. These methods are not called inside the class in question. To override this behaviour methods can be called directly, or by breaking the static binding: (this).attrname
_fetch_name -

Called when an attribute name is looked upon an object:

expr.name
If general callback method _fetch exists then it will receive all the attribute assignments that didn't match any of specific _fetch_* methods.
_store_name (value)

Called when an attribute name is assigned an object:

expr.name
If general callback method _store exists then it will receive all the attribute accesses that didn't match any of specific _store_* methods.
_defined_name -

Called when it is checked if an attribute name exists on object.

defined expr.name
If general callback method _defined exists then it will receive all the checks that didn't match any of specific _defined_* methods.
_dispose_name -

Called when an attribute name is deleted from an object:

delete expr.name
If general callback method _dispose exists then it will receive all the deletes that didn't match any of specific _dispose_* methods.
_fetch (name)

Called when an attribute is looked upon an object:

expr.name
_store (name, value)

Called when an attribute is assigned on to an object:

expr.name = value
_defined (name)

Called when an attribute is checked to exist on an object:

defined expr.name
_dispose (name)

Called when an attribute is deleted from an object:

delete expr.name
Reference emulation methods.
_get (index)

Called when an reference looked upon an object:

expr[index]
_set (index, value)

Called when an reference is assigned on to an object:

expr[index] = value
_append (value)

Called when an value is appended to an object:

expr[] = value
_check (index)

Called when an reference is checked to exist on an object:

defined expr[index]
_delete (index)

Called when an reference is deleted from an object:

delete expr[index]
Callable emulation methods.
_execute (parameters...)

Called when object is accessed as it if were a function.

expr(parameters...)
_invoke (methodName, parameters...)

Called when an method is invoked on an object. When invoking statically bound method inside class this method is not called. To override this behaviour break the static binding: (this).methodName(parameters..)

expr.methodName(parameters...)
Serialization callbacks.
_sleep -

Sleep method is called when an object is serialized. It should return a list of member variables that should be serialized. Also at this point the object can free reserved resources, such as database connections. That is, of course, matter of contract. When object is serialized the members of it are not acccessed through normal _fetch callback, if that exists, instead they are taken internally.

Note also that _sleep is called for each inherited class, if any and if it the method exists. Otherwise default behaviour is used which is to serialize every member variable of and object.

_wakeup -

Wakeup is called for each level of class, starting from bottom. Before calling the serialized fields are restored (for class level being calledr).

Reference proxy methods
_getRef -

When an object is encapsuled with ref() function it will performs as proxy. This method should return the actual value into which this ref is pointing.

_setRef (concreteValue)

When reference is assigned this method is called.

&ref = concreteValue

Other methods
_enumeration -

Should returned enumeration (array, module or class containg hasMore and next methods), or an other object from which an enumeration can be produced.

_in (element)

Called when element membership is checked for

element in object

_has (methodName)

Called when method existence membership is checked for

object has methodName

Contributes notes:
2003-03-13 Simo Note on _defined and _defined_name
Function should return undefined if given attribute doesn't exist and something else (the value for example) if it exists.
I thought it should return boolean value but it shouldn't since both true and false are != undefined =)
Add a note
What's new | Anvil