In many ways these values should be considered constant, but it is possible for a program to replace them with extended versions, provided they don't break the behavior of the base classes defined here. Since there is no good mechanism to handle such extending in several steps, pike libraries should preferably ensure that the base classes defined here provide required functionality directly.
Since resolving using the dot operator in e.g. Val.null is done at compile time, replacement of these values often must take place very early (typically in a loader before the bulk of the pike code is compiled) to be effective in such cases. For this reason, pike libraries should use dynamic resolution through e.g.
Objects that represent the boolean values true and false. In a boolean context these evaluate to true and false, respectively.
0, respectively, when cast to integer, and
"0"when cast to string. They do however not compare as equal to the integers 1 and 0, or any other values. Val.true only compares (and hashes) as equal with other instances of True (although there should be as few as possible). Similarly, Val.false is only considered equal to other False instances.
Protocols.JSONuses these objects to represent the JSON literals
The correct way to programmatically recognize these values is something like
if (objectp(something) && ([object]something)->is_val_true) ...
if (objectp(something) && ([object]something)->is_val_false) ...
respectively. See Val.null for rationale.
Pike natively uses integers (zero and non-zero) as booleans. These objects don't change that, and unless there's a particular reason to use these objects it's better to stick to e.g. 0 and 1 for boolean values - that is both more efficient and more in line with existing coding practice. These objects are intended for cases where integers and booleans occur in the same place and it is necessary to distinguish them.
- Variable null
Object that represents a null value.
In general, null is a value that represents the lack of a real value in the domain of some type. For instance, in a type system with a null value, a variable of string type typically can hold any string and also null to signify no string at all (which is different from the empty string). Pike natively uses the integer 0 (zero) for this, but since 0 also is a real integer it is sometimes necessary to have a different value for null, and then this object is preferably used.
This object is false in a boolean context. It does not cast to anything, and it is not equal to anything else but other instances of Null (which should be avoided).
This object is used by the Sql module to represent SQL NULL, and it is used by
Protocols.JSONto represent the JSON literal
Do not confuse the null value with UNDEFINED. Although UNDEFINED often is used to represent the lack of a real value, and it can be told apart from an ordinary zero integer with some effort, it is transient in nature (for instance, it automatically becomes an ordinary zero when inserted in a mapping). That makes it unsuitable for use as a reliable null value.
The correct way to programmatically recognize Val.null is something like
if (objectp(something) && ([object]something)->is_val_null) ...
That way it's possible for other code to replace it with an extended class, or create their own variants which needs to behave like Val.null.
The Oracle glue currently uses static null objects which won't be affected if this object is replaced.