ChangeEntry

Inherits from Value
Sealed

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]

Instance Methods

seq source

The monotonic sequence number assigned when the entry was logged.

Examples

(Workspace changes select: [:e | true]) first seq   // => _
className source

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   // => _
selector source

The patched selector (Symbol), or nil for new-class entries.

Examples

(Workspace changes select: [:e | true]) first selector   // => _
kind source

The kind of patch: #instance, #class, #'new-class', or #unknown.

intent source

The recorded intent: #durable or #ephemeral.

isFlushable source

Whether the patch is flushable to disk (the class has an in-project source file).

isDurable source

Whether the entry was logged with durable intent.

Examples

Workspace changes select: [:e | e isDurable]   // => _
isEphemeral source

Whether the entry was logged with ephemeral (exploratory) intent.

authorKind source

Who made the change: #human or #agent (audit metadata, not a filter).

isAgent source

Whether the change came from an agent (MCP tool).

isHuman source

Whether the change came from a human (REPL / browser).

sourceFile source

The recorded source file path (String), or nil for stdlib / dynamic classes that have no on-disk source.

isOrphan 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]   // => _
isPriorEpoch source

Whether the entry belongs to a prior workspace epoch (logged before the most recent restart — its memory state was lost).

isActive source

Whether the entry is part of the active dirty view: current epoch and not orphaned. Active entries are the live, re-appliable changes.

isNewClass source

Whether this entry created a new class (kind #'new-class', no selector).

printString source

Developer-readable representation, e.g. "Counter>>increment" or "Counter (new-class)".

Examples

(Workspace changes select: [:e | true]) first printString   // => _

Inherited Methods

From Value

inspect

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

class

Return the class of the receiver.

Examples

42 class              // => Integer
"hello" class         // => String
isNil

Test if the receiver is nil. Returns false for all objects except nil.

Examples

42 isNil              // => false
nil isNil             // => true
notNil

Test if the receiver is not nil. Returns true for all objects except nil.

Examples

42 notNil             // => true
nil notNil            // => false
ifNil: _nilBlock

If the receiver is nil, evaluate nilBlock. Otherwise return self.

Examples

42 ifNil: [0]         // => 42
nil ifNil: [0]        // => 0
ifNotNil: notNilBlock

If the receiver is not nil, evaluate notNilBlock with self.

Examples

42 ifNotNil: [:v | v + 1]   // => 43
nil ifNotNil: [:v | v + 1]  // => nil
ifNil: _nilBlock ifNotNil: notNilBlock

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
ifNotNil: notNilBlock ifNil: _nilBlock

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
printString

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"
displayString

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

Inspect the receiver.

Examples

42 inspect             // => "42"
yourself Sealed

Return the receiver itself. Useful for cascading side effects.

Examples

42 yourself            // => 42
hash

Return a hash value for the receiver.

Examples

42 hash
respondsTo: selector Sealed

Test if the receiver responds to the given selector.

Examples

42 respondsTo: #abs    // => true
fieldNames Sealed

Return the names of fields.

Examples

42 fieldNames             // => #()
fieldAt: name Sealed

Return the value of the named field.

Examples

object fieldAt: #name
fieldAt: name put: value Sealed

Set the value of the named field (returns new state).

Examples

object fieldAt: #name put: "Alice"
perform: selector Sealed

Send a unary message dynamically.

Examples

42 perform: #abs       // => 42
perform: selector withArguments: args Sealed

Send a message dynamically with arguments.

Examples

3 perform: #max: withArguments: #(5)   // => 5
subclassResponsibility

Raise an error indicating this method must be overridden by a subclass.

Examples

self subclassResponsibility
notImplemented

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
show: aValue

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: "
showCr: aValue

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"
isKindOf: aClass

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)
error: message

Raise an error with the given message.

Examples

self error: "something went wrong"

From ProtoObject

== other

Test value equality (Erlang ==).

Examples

42 == 42           // => true
"abc" == "abc"     // => true
/= other

Test value inequality (negation of ==).

Examples

1 /= 2             // => true
42 /= 42           // => false
class

Return the class of the receiver.

Examples

42 class            // => Integer
"hello" class       // => String
doesNotUnderstand: selector args: arguments

Handle messages the receiver does not understand. Override for custom dispatch.

Examples

42 unknownMessage   // => ERROR: does_not_understand
perform: selector withArguments: arguments

Send a message dynamically with an arguments list.

Examples

42 perform: #abs withArguments: #()   // => 42
performLocally: selector withArguments: arguments

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)
perform: selector withArguments: arguments timeout: timeoutMs

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