ClassThe class of classes: Integer, List, and every user-defined class are instances of Class. Define one with Name <- { ... } (a subclass with Parent <- Name <- { ... }), reopen one with Name <-- { ... }, and reflect with name / parent / class. Note that on classes == is the SUBTYPE test, and Pattern ~ x is instance-of.
Pattern-matching support for classes.
Whether a class named by the Symbol or String argument is defined -- Class.exists?:#Point, or Class.exists?:#'[IO]File' for a namespaced class. The way to ask without reading the name, which would raise a NameError if it is unbound.
On classes, == is the SUBTYPE test: A == B is true when A is B or a descendant of B (metaclasses compare the same way) -- so it is deliberately not symmetric.
Integer == Object "* -> true Object == Integer "* -> false
Forbid instantiating this class itself: new on it raises, while subclasses may still be instantiated. Answers the class.
The class Class itself -- every class is an instance of Class.
Integer.class.name "* -> Class
Mix a mixin class into the receiver: the mixin's methods join dispatch (they can shadow a parent's), and its instance variables and init join instantiation. If the mixin defines a class-side assertMeetsRequirements:, that check runs at the end of the enclosing class body, once the host class is fully defined. Answers the mixin.
Mixin <- M <- { hi -> { 'hi' } }; A <- { .mix:M }; A.new.hi "* -> hi
The class's name as a String, including any namespace ('[IO]File').
Integer.name "* -> Integer
The superclass, or nil for Object (the root).
Integer.parent.name "* -> Object
Freeze the class: further extension (Name <-- { ... }, mix:) and subclassing are refused with an error. Answers the class.
A class used as a match pattern (Integer ~ x / case when:Integer) is an instance-of test: ~ dispatches on the left (the pattern), and a class pattern answers whether the subject can?: it.
Integer ~ 5 "* -> true Integer ~ 'x' "* -> false