ObjectabstractThe universal root: every value is an Object, and every class inherits from it. It carries the protocol everything shares -- identity and equality (==: / !=: / ~:), rendering (s / pp / print), reflection (class / can?: / doc / docFor: / perform:args:), and raising a value as an error (throw).
Defaults every object inherits: the existence test, truthiness, unary +, and the comparison operators derived from <:.
Every object can open a case expression on itself.
Everything except nil/false is truthy, so !self is false here; nil and the booleans override. (-self is handled per numeric type, not here.)
The negation of ==:, defined once here -- overriding ==: is enough to get != right.
1 != 2 "* -> true
Unary plus (+self) is identity for every type.
Less-than-or-equal, derived from <: as !(x < self).
Equality. Object's default is IDENTITY -- true only when both sides are the very same object (scalars compare by value). Value classes override it (numbers compare across Integer/Float, collections structurally); any ==: override must be matched by a hash override.
A <- {}; var a = A.new; a == a "* -> true A.new == A.new "* -> false
Greater-than, derived from <: (defined natively per primitive type, and on the booleans): any class that defines <: gets >:/<=:/>=: for free.
Greater-than-or-equal, derived from <: as !(self < x).
Whether the receiver 'can do' the argument -- overloaded by argument. With a Symbol or String selector: does the receiver implement that method? (A Class receiver reports its INSTANCE methods; ask .meta.can?: for class-side ones.) With a Class: is the receiver an instance of it -- mixins and superclasses included?
List.can?:#add: "* -> true 3.can?:Integer "* -> true 3.can?:String "* -> false
Match self against the arms in the block: inside it, self is a Case whose subject is this object; answers the first matching arm's result (nil when nothing matches and no default: is given).
3.case:{ .when:1 do:{ 'one' }; .when:3 do:{ 'three' }; .default:{ 'other' } } "* -> three
The receiver's class, as a Class object.
3.class.name "* -> Integer
true for every value except nil (Nil overrides this to false) — the fundamental existence test, used by whileDefinedDo: and friends.
'x'.defined? "* -> true nil.defined? "* -> false
The receiver's class-level reference doc, or nil. Mirrors can?:: a Class answers for itself, an instance for its class.
The reference doc for a selector, or nil. A Class receiver answers for instance methods; .meta.docFor: for class-side ones -- the same sides can?: reports.
The receiver's hash code. Scalars hash structurally; instances default to IDENTITY, matching Object's identity ==:. A class that overrides ==: with value semantics must override hash to match -- equal values must hash equal, or map lookups miss.
The default initializer: does nothing and answers the receiver. Instantiation runs it on each fresh instance; classes define their own init (or keyword init: forms) to set up state.
Send a selector reflectively: the String selector, with the List's elements as arguments (nil is an empty argument list). Raises the same MessageNotUnderstood a direct send would.
3.perform:'+:' args:#( 4 ) "* -> 7
A structural, canonical dump of the value graph for debugging and inspection -- escaped strings, instance variables, intrinsic collections. Width-aware (wraps to the console width; pp: takes an explicit width) and never calls s.
'hi'.pp "* -> 'hi' #( 1 2 ).pp "* -> #(1 2)
As pp, but wrapped to the given width (a positive Integer) instead of the console's.
Render the receiver with s and write it to standard output with a trailing newline. Answers nil.
'hello'.print "* prints hello
The receiver rendered for humans, as a String. The default for a value with no intrinsic form falls back to the structural pp rendering; types with one (Integer, String, Error, ...) override it.
A <- { |@x @y| init -> { @x = 1; @y = 2 } }; A.new.s "* -> A{@x: 1 @y: 2}
Seal the receiver against further extension: value <-- { ... } on it is refused afterwards. On an instance this freezes its eigenclass; on a value type (an Integer, a String, ...) it targets the type's shared class, matching how value <-- { ... } extends it. Answers the receiver. (Class#sealed! handles class receivers.)
Raise the receiver as an exception: unwind to the nearest enclosing catch: whose handler matches (by the handler parameter's declared type). Any value can be thrown, not just Error instances.
{ 'boom'.throw }.catch:{ |e| e } "* -> boom
The match operator, pattern ~ subject -- it dispatches on the LEFT operand (the pattern). Object's default is plain equality (delegates to ==:); pattern kinds override it: a Class matches its instances (Integer ~ 3), a Block runs as a predicate, a Regex matches strings. case:'s when: clauses match with it.
3 ~ 3 "* -> true Integer ~ 3 "* -> true