//
// Copyright (c) 2006, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 2 Dec 05 Brian Frank Creation
//
**
** Obj is the root class of all classes.
**
abstract class Obj
{
//////////////////////////////////////////////////////////////////////////
// Constructor
//////////////////////////////////////////////////////////////////////////
**
** Obj constructor for subclasses.
**
protected new make()
//////////////////////////////////////////////////////////////////////////
// Virtuals
//////////////////////////////////////////////////////////////////////////
**
** Compare this object to the specified for equality. This method may
** be accessed via the == and != shortcut operators. If not overridden
** the default implementation compares for reference equality using
** the === operator. If this method is overridden, then hash() must
** also be overridden such that any two objects which return true for
** equals() must return the same value for hash(). This method must
** accept 'null' and return false.
**
virtual Bool equals(Obj? that)
**
** Return a negative integer, zero, or a positive integer if this object
** is less than, equal to, or greater than the specified object:
** this < that => <0
** this == that => 0
** this > that => >0
**
** This method may also be accessed via the '<' '<=' '<=>' '>=' and '>'
** shortcut operators. If not overridden the default implementation
** compares the `toStr` representations. Also see
** [docLang]`docLang::Expressions#shortcuts`.
**
** Examples:
** 3.compare(8) => -1
** 8.compare(3) => 1
** 8.compare(8) => 0
** 3 <=> 8 => -1 // shortcut for 3.compare(8)
**
virtual Int compare(Obj that)
**
** Return a unique hashcode for this object. If a class overrides hash()
** then it must ensure if equals() returns true for any two objects then
** they have same hash code.
**
virtual Int hash()
**
** Return a string representation of this object.
**
virtual Str toStr()
**
** Trap a dynamic call for handling. Dynamic calls are invoked
** with the -> shortcut operator:
** a->x a.trap("x", null)
** a->x() a.trap("x", null)
** a->x = b a.trap("x", [b])
** a->x(b) a.trap("x", [b])
** a->x(b, c) a.trap("x", [b, c])
** The default implementation provided by Obj attempts to use
** reflection. If name maps to a method, it is invoked with the
** specified arguments. If name maps to a field and args.size
** is zero, get the field. If name maps to a field and args.size
** is one, set the field and return args[0]. Otherwise throw
** UnknownSlotErr.
**
virtual Obj? trap(Str name, Obj?[]? args := null)
**
** This method called whenever an it-block is applied to
** an object. The default implementation calls the function
** with 'this', and then returns 'this'.
**
virtual This with(|This| f)
//////////////////////////////////////////////////////////////////////////
// Type
//////////////////////////////////////////////////////////////////////////
**
** Return if this Obj is [immutable]`docLang::Concurrency#immutability`
** and safe to share between threads:
** - an instance of a const class
** - the result of `toImmutable` on `List`, `Map`, or `Buf`
** - a Func object may or may not be immutable - see `sys::Func`.
** - other instances are assumed mutable and return false
**
Bool isImmutable()
**
** Get an immutable representation of this instance or throw
** NotImmutableErr if this object cannot be represented as an
** immutable:
** - if type is const, return this
** - if already an immutable List, Map, Buf, or Func return this
** - if a List, then attempt to perform a deep clone by
** calling toImmutable on all items
** - if a Map, then attempt to perform a deep clone by
** calling toImmutable on all values (keys are already immutable)
** - some Funcs can be made immutable - see `sys::Func`
** - if a Buf create immutable copy, see `sys::Buf`
** - any other object throws NotImmutableErr
**
This toImmutable()
**
** Get the 'Type' instance which represents this object's class.
** Also see`Type.of` or `Pod.of`.
**
Type typeof()
//////////////////////////////////////////////////////////////////////////
// Utils
//////////////////////////////////////////////////////////////////////////
**
** Write 'x.toStr' to standard output followed by newline. If 'x' is
** null then print "null". If no argument is provided then print
** an empty line.
**
static Void echo(Obj? x := "")
}