ChangeEntry
ChangeEntry — One recorded in-memory method mutation (ADR 0082 Phase 1).
A ChangeEntry is an immutable snapshot of a single entry in the workspace
ChangeLog: the class and selector that were patched, the kind of patch,
whether the caller intended it as durable, whether it is flushable to disk,
who made it, and the derived restart-state flags (orphan / prior-epoch /
active). Entries are produced by Workspace changes and surfaced to
ChangeLog do: / ChangeLog select: blocks; they are not constructed
directly by user code.
The underlying record lives in beamtalk_workspace_changelog.erl; this
value object wraps the tagged map that the FFI returns.
Examples
Workspace changes do: [:e | Transcript show: e authorKind]
Workspace changes select: [:e | e isOrphan]
Methods
Instance Methods
The monotonic sequence number assigned when the entry was logged.
Examples
(Workspace changes select: [:e | true]) first seq // => _
The name (Symbol) of the class that was patched.
Named className rather than class because every object already
responds to class (returning the metaclass).
Examples
(Workspace changes select: [:e | true]) first className // => _
The patched selector (Symbol), or nil for new-class entries.
Examples
(Workspace changes select: [:e | true]) first selector // => _
The kind of patch: #instance, #class, #'new-class', or #unknown.
The recorded intent: #durable or #ephemeral.
Whether the patch is flushable to disk (the class has an in-project source file).
Whether the entry was logged with durable intent.
Examples
Workspace changes select: [:e | e isDurable] // => _
Whether the entry was logged with ephemeral (exploratory) intent.
Who made the change: #human or #agent (audit metadata, not a filter).
Whether the change came from an agent (MCP tool).
Whether the change came from a human (REPL / browser).
The recorded source file path (String), or nil for stdlib / dynamic classes that have no on-disk source.
Whether the entry is orphaned — its prev_source no longer matches disk after a workspace restart, so the patch can no longer be reconciled.
Examples
Workspace changes select: [:e | e isOrphan] // => _
Whether the entry belongs to a prior workspace epoch (logged before the most recent restart — its memory state was lost).
Whether the entry is part of the active dirty view: current epoch and not orphaned. Active entries are the live, re-appliable changes.
Whether this entry created a new class (kind #'new-class', no selector).
Developer-readable representation, e.g. "Counter>>increment" or "Counter (new-class)".
Examples
(Workspace changes select: [:e | true]) first printString // => _
Inherited Methods
From Value
Return a developer-readable string representation showing fields.
Produces ClassName(field: value, ...). Field values are recursively
inspected — strings are quoted, nested objects show their own inspect.
A class with no fields produces ClassName().
Examples
ValuePoint x: 3 y: 4 inspect // => "ValuePoint(x: 3, y: 4)"
ValuePoint new inspect // => "ValuePoint(x: 0, y: 0)"
From Object
Return the class of the receiver.
Examples
42 class // => Integer
"hello" class // => String
Test if the receiver is nil. Returns false for all objects except nil.
Examples
42 isNil // => false
nil isNil // => true
Test if the receiver is not nil. Returns true for all objects except nil.
Examples
42 notNil // => true
nil notNil // => false
If the receiver is nil, evaluate nilBlock. Otherwise return self.
Examples
42 ifNil: [0] // => 42
nil ifNil: [0] // => 0
If the receiver is not nil, evaluate notNilBlock with self.
Examples
42 ifNotNil: [:v | v + 1] // => 43
nil ifNotNil: [:v | v + 1] // => nil
If nil, evaluate nilBlock; otherwise evaluate notNilBlock with self.
Examples
42 ifNil: [0] ifNotNil: [:v | v + 1] // => 43
nil ifNil: [0] ifNotNil: [:v | v + 1] // => 0
If not nil, evaluate notNilBlock with self; otherwise evaluate nilBlock.
Examples
42 ifNotNil: [:v | v + 1] ifNil: [0] // => 43
nil ifNotNil: [:v | v + 1] ifNil: [0] // => 0
Return a developer-readable string representation.
Default implementation returns "a ClassName". Subclasses such as
Integer, String, and List override this to return richer output.
Examples
42 printString // => "42"
Return a user-facing string representation for display purposes.
Default implementation delegates to printString. Subclasses such as
String and Symbol override this to return a more readable form without
developer annotations (e.g. no surrounding quotes or # prefix).
Examples
42 displayString // => "42"
Inspect the receiver.
Examples
42 inspect // => "42"
Return the receiver itself. Useful for cascading side effects.
Examples
42 yourself // => 42
Return a hash value for the receiver.
Examples
42 hash
Test if the receiver responds to the given selector.
Examples
42 respondsTo: #abs // => true
Return the names of fields.
Examples
42 fieldNames // => #()
Return the value of the named field.
Examples
object fieldAt: #name
Set the value of the named field (returns new state).
Examples
object fieldAt: #name put: "Alice"
Send a unary message dynamically.
Examples
42 perform: #abs // => 42
Send a message dynamically with arguments.
Examples
3 perform: #max: withArguments: #(5) // => 5
Raise an error indicating this method must be overridden by a subclass.
Examples
self subclassResponsibility
Raise an error indicating this method has not yet been implemented.
Use this for work-in-progress stubs. Distinct from subclassResponsibility,
which signals an interface contract violation.
Examples
self notImplemented
Send aValue to the current transcript without a trailing newline.
Nil-safe: does nothing when no transcript is set (batch compile, tests).
Examples
42 show: "value: "
Send aValue to the current transcript followed by a newline.
Nil-safe: does nothing when no transcript is set (batch compile, tests).
Examples
42 showCr: "hello world"
Test if the receiver is an instance of aClass or any of its subclasses.
For class-object receivers, follows Smalltalk semantics: self class
is the metaclass, so the check walks the parallel metaclass hierarchy.
The parallel chain is grounded at ProtoObject class superclass == Class
(ADR 0036), so the metaclass tower merges into the instance-side
Class → Behaviour → Object → ProtoObject chain. As a result,
Integer isKindOf: Object and Integer isKindOf: Class both return true.
Examples
42 isKindOf: Integer // => true
42 isKindOf: Object // => true
#foo isKindOf: Symbol // => true
#foo isKindOf: String // => false
Integer isKindOf: Number // => false (metaclass chain, not instance chain)
Integer isKindOf: Number class // => true (Number class is in the parallel chain)
Integer isKindOf: Object // => true (grounded — Object is reachable via the metaclass tower)
Integer isKindOf: Class // => true (Integer class inherits from Class)
Raise an error with the given message.
Examples
self error: "something went wrong"
From ProtoObject
Test value equality (Erlang ==).
Examples
42 == 42 // => true
"abc" == "abc" // => true
Test value inequality (negation of ==).
Examples
1 /= 2 // => true
42 /= 42 // => false
Return the class of the receiver.
Examples
42 class // => Integer
"hello" class // => String
Handle messages the receiver does not understand. Override for custom dispatch.
Examples
42 unknownMessage // => ERROR: does_not_understand
Send a message dynamically with an arguments list.
Examples
42 perform: #abs withArguments: #() // => 42
Execute a class method in the caller's process, bypassing gen_server dispatch.
The caller takes responsibility for knowing the method does not mutate class state. Useful for long-running class methods that would otherwise block the class object's gen_server.
Limitations: only resolves methods defined directly on the target class
module (does not walk the superclass chain). Class variables and self
are not available to the method (nil and #{} are passed).
Examples
MyClass performLocally: #run:ctx: withArguments: #(input, ctx)
Send a message dynamically with an arguments list and explicit timeout.
The timeout (in milliseconds or #infinity) applies to the gen_server:call
when the receiver is an actor. For value types, timeout is ignored.
Examples
actor perform: #query withArguments: #(sql) timeout: 30000