# Package: Kernel-Objects

## Class: APIError

### Introduction

**Environment: `container`**

APIError is a class to interact with error object returned by Engine.

An APIError object has the following attributes:

* code: the error code
* args: the arguments of the error
* detail: the detailed message of the error

For example:

```smalltalk
error := nil.
client := HTTPClient new.
client url: 'http://www.non-exist-host.com/path'.
[ client get ] onErrorDo: [ :ex | error := ex ].
error code = 'http-request-error'.
```

### Instance Method

#### Category: accessing

* **`args`** - Get error args.
* **`code`** - Get error code.
* **`detail`** - Get error detail message.

## Class: Boolean

### Introduction

**Environment: `container`**

Boolean is a subclass of Object. It has two instances: `true` and `false`.

We can use the `ifTrue:` and `ifFalse:` methods to evaluate a block depending on the value of the receiver.

```smalltalk
count := 0.
lf = 'There is a problem with my internet' ifTrue: [ count := count + 1 ].

lf = 'There is a problem with my internet'
   ifTrue: [ count := count + 1 ]
   ifFalse: [ count := count - 1 ].
```

We can also use the `and:` and `or:` methods to evaluate a block depending on the value of the receiver.

```smalltalk
lf = 'a' or: 'lf = 'b'.
lf = 'a' or: ['lf = 'b'].

a > 10 and: a < 20.
```

## Class: CSVReader

### Introduction

**Environment: `container`**

This is a class to read CSV into Mindscript array.

For example:

```smalltalk
"The following example creates a one-row array: {{1. 2. 3}}"
CSVReader fromString: '1,2,3'.
"The following example creates a two-row array: {{1. 2. 3}. {4. 5. 6}}"
CSVReader fromString: '1,2,3
4,5,6'.
```

### Class Method

#### Category: convenience

* **`fromString:`** - Read a CSV string and return an array.

  For example:

  ```smalltalk
  "The following example creates a one-row array: {{1. 2. 3}}"
  CSVReader fromString: '1,2,3'.
  "The following example creates a two-row array: {{1. 2. 3}. {4. 5. 6}}"
  CSVReader fromString: '1,2,3
  4,5,6'.
  ```

## Class: Character

### Introduction

**Environment: `container`**

A Character can represent any single character from the Unicode character set.

We can create a character by using the literal syntax, which is a single character enclosed in single quotes. For example:

```smalltalk
aCharacter := $A.
```

In this example, aCharacter is an instance of Character representing the uppercase letter `A`.

We can also create a character by using the integer value of a character. For example:

```smalltalk
aLineFeed := Character value: 10.
```

### Class Method

#### Category: accessing untypeable characters

* **`cr`** - Answer the character representing a carriage return.
* **`lf`** - Answer the character representing a linefeed.
* **`null`** - Answer the character representing a null.
* **`space`** - Answer the character representing a space.
* **`tab`** - Answer the character representing a tab.

#### Category: instance creation

* **`value:`** - Answer the character whose value is an integer.

  For example:

  ```smalltalk
  aLineFeed := Character value: 10.
  ```

### Instance Method

#### Category: converting

* **`asCharacter`** - Answer the receiver itself.

  For example:

  ```smalltalk
  $a asCharacter = $a.
  ```
* **`asInteger`** - Answer the receiver's character code.

  For example:

  ```smalltalk
  $A asInteger = 65.
  ```
* **`asLowercase`** - If the receiver is uppercase, answer its matching lowercase Character.

  For example:

  ```smalltalk
  $A asLowercase = $a.
  ```
* **`asString`** - Answer the receiver as a string.

  For example:

  ```smalltalk
  $A asString = 'A'.
  ```
* **`asUppercase`** - If the receiver is lowercase, answer its matching uppercase Character.

  For example:

  ```smalltalk
  $a asUppercase = $A.
  ```

## Class: Dictionary

### Introduction

**Environment: `container`**

A dictionary is a collection of elements that associate a key object with a value object. It can be viewed as a set of associations.

It is used when you need a collection of objects which can be accessed with a key. For example, if you associate some words with a definition, the word will be the key and the definition will be the value. Both of them can be any kind of objects.

Associations are used to fetch the value using a key ( key -> value).

Following common used methods:

* `new` create a new dictionary.
* `size` return the size of the dictionary.
* `keys` return the keys of the dictionary.
* `at:` get the value associated with the given key.
* `at:put:` set the value associated with the given key.
* `asDictionary` return a dictionary containing the elements of the receiver.

```smalltalk
aDictionary := {
                   ('key' -> 'value').
                   ('key2' -> 'value2') } asDictionary.
aDictionary at: 'key'. "value"
aDictionary size. "2"
aDictionary keys. "{'key' 'key2'}"
aDictionary at: 'key' put: 'new value'
```

### Class Method

#### Category: instance creation

* **`new`** - answer a new Dictionary.

### Instance Method

#### Category: accessing

* **`add:`** - Add the newObject (association) to the receiver.

  For example:

  ```smalltalk
  dict := Dictionary new.
  dict add: ('z' -> 'ccc'). "dict contains key: 'z' and value 'ccc'"
  dict at: 'z'. "returns 'ccc'"
  ```
* **`addAll:`** - Adding all elements of a Dictionary to the receiver, which is the primary Dictionary.

  For example:

  ```smalltalk
  dict := Dictionary new.
  "dict contains key: 'y' and value 'bbb', key: 'z' and value 'ccc'"
  dict addAll: { ('y' -> 'bbb'). ('z' -> 'ccc') } asDictionary. 
  dict at: 'y'. "returns 'bbb'"
  dict at: 'z'. "returns 'ccc'"
  ```
* **`associationAt:`** - Answer the value associated with the given key.

  For example:

  ```smalltalk
  dict := { ('x' -> 'aaa'). ('y' -> 'bbb'). } asDictionary.
  asn := dict associationAt: 'y'. "asn = ('y' -> 'bbb')"
  ```
* **`associationAt:ifAbsent:`** - Answer the key/value Association for the given key. Evaluate aBlock (answering the result) if the key is not found.

  For example:

  ```smalltalk
  dict := Dictionary new.
  dict add: ('z' -> 'ccc'). "dict contains key: 'z' and value 'ccc'"
  dk := dict associationAt: 'ccc' ifAbsent: [ 'xyz' ]. "dk = 'xyz'"
  dk := dict associationAt: 'z' ifAbsent: [ 'xyz' ]. "dk = ('z' -> 'ccc')"
  ```
* **`associations`** - Answer with all associations in the Dictionary, as a List.

  For example:

  ```smalltalk
  dict := { ('x' -> 'aaa'). ('y' -> 'bbb'). } asDictionary.
  dict2 := { ('z' -> 'ccc') } asDictionary.
  dasn := dict associations. "dasn is a List of associations "
  dasn do: [ :asn | dict2 add: asn ].
  "dict2 = { ('x' -> 'aaa'). ('y' -> 'bbb'). ('z' -> 'ccc') }"
  ```
* **`at:`** - answer the value associated with the given key.
* **`at:ifAbsent:`** - Get the value of the parameter with specified name, and specify a default value if absent. The parameter for the default value can be

  * a code block, which will be evaluated if the parameter is absent.
  * a value, which will be returned if the parameter is absent.

  For example:

  ```smalltalk
  dict := Dictionary new.
  "cash_flow should be 100."
  cash_flow := (dict at: 'cash_flow' ifAbsent: 100).
  dict at: 'cash_flow' put: 200.
  "cash_flow should be 200."
  cash_flow := (dict at: 'cash_flow' ifAbsent: 100).
  ```
* **`at:ifAbsentPut:`** - Answer the value associated to the given key. If the key is not found, evaluate aBlock and associate the result to aKey before returning.

  For example:

  ```smalltalk
  dict := Dictionary new.
  dict add: ('z' -> 'ccc'). "dict contains key: 'z' and value 'ccc'"
  dk := dict at: 'z' ifAbsentPut: [ 'xyz' ]. "dk = ('z' -> 'ccc')"
  dk := dict at: 'y' ifAbsentPut: [ 'xyz' ]. "dk = nil"
  dk := dict at: 'y'. "dk = ('y' -> 'xyz')"
  ```
* **`at:ifPresent:`** - If aKey is absent, answer nil. Else, evaluate aBlock passing the associated value and answer the result of the invocation.

  For example:

  ```smalltalk
  dict := Dictionary new.
  dict add: ('z' -> 'ccc'). "dict contains key: 'z' and value 'ccc'"
  dk := dict at: 'z' ifPresent: [ :val | val + 'xyz' ]. "dk = 'cccxyz'"
  ```
* **`at:put:`** - Set the value associated with the given key.
* **`atAll:`** - Answer with the values associated with the given keys.

  For example:

  ```smalltalk
  dict := ('x' -> 'aaa'). ('y' -> 'bbb'). ('z' -> 'ccc') } asDictionary.
  dk := dict atAll: { 'x'. 'r'. 'z' } asList. "dk = { 'aaa'. 'ccc' }"
  ```
* **`keyAtValue:`** - Answer the key associated to the given value, or nil if the value is not found.

  For example:

  ```smalltalk
  dict := { ('x' -> 'aaa'). ('y' -> 'bbb'). } asDictionary.
  kav := dict keyAtValue: 'bbb'. "kav = 'y'"
  "Note: if there is more than one keys with the same value, it will return an arbitrary key among them."
  ```
* **`keyAtValue:ifAbsent:`** - Answer the key associated to the given value. Evaluate exceptionBlock (answering the result) if the value is not found.

  For example:

  ```smalltalk
  dict := Dictionary new.
  dict add: ('z' -> 'ccc'). "dict contains key: 'z' and value 'ccc'"
  dk := dict keyAtValue: 'ccc' ifAbsent: [ 'xyz' ]. "dk = 'z'"
  dk := dict keyAtValue: 'z' ifAbsent: [ 'xyz' ]. "dk = 'xyz'"
  ```
* **`keys`** - answer keys as an array in the receiver.
* **`size`** - answer the number of associations in the receiver.
* **`values`** - answer dictionary values as an array in the receiver.

#### Category: enumerating

* **`associationsDo:`** - Pass each association in the dictionary to aBlock.

  For example:

  ```smalltalk
  dict := { ('x' -> 'aaa'). ('y' -> 'bbb'). } asDictionary.
  dict2 := { ('z' -> 'ccc') } asDictionary.
  dict associationsDo: [ :asn | dict2 add: asn ]. 
  "dict2 = { ('x' -> 'aaa'). ('y' -> 'bbb'). ('z' -> 'ccc') }"
  ```
* **`collect:`** - Evaluate the given block for each element of the receiver and return a new Dictionary with the results.

  For example:

  ```smalltalk
  ({ ('key' -> 'value').
    ('key2' -> 'value2') } asDictionary collect: [ :key :value | 
   key -> (value , ' new') ]) asJson.
  ```
* **`detect:`** - Evaluate aBlock with each of the receiver's elements as the argument until aBlock evaluates to true. Answer the first element for which aBlock evaluates to true.

  For example:

  ```smalltalk
  "Return ('key2' -> 'value2')."
  { ('key' -> 'value').
    ('key2' -> 'value2') } asDictionary detect: [ :key :value | 
   key = 'key2' ].
  ```
* **`detect:ifFound:`** - Evaluate aBlock with each of the receiver's elements as the argument until aBlock evaluates to true. If some element evaluates aBlock to true, then cull this element into foundBlock and answer the result of this evaluation.

  For example:

  ```smalltalk
  "Return ('key2_matched' -> 'value2_matched')."
  { ('key' -> 'value').
    ('key2' -> 'value2') } asDictionary detect: [ :key :value | 
   key = 'key2' ] ifFound: [ :key :value | 
   (key , '_matched') -> (value , '_matched') ].
  ```
* **`detect:ifFound:ifNone:`** - Evaluate aBlock with each of the receiver's elements as the argument until aBlock evaluates to true. If some element evaluates aBlock to true, then cull this element into foundBlock and answer the result of this evaluation. If none evaluate to true, then evaluate exceptionBlock

  For example:

  ```smalltalk
  "Return ('key2_matched' -> 'value2_matched')."
  { ('key' -> 'value').
    ('key2' -> 'value2') } asDictionary detect: [ :key :value | 
   key = 'key2' ] ifFound: [ :key :value | 
   (key , '_matched') -> (value , '_matched') ] ifNone: [ 
   'defaultKey' -> 'defaultValue' ].
  ```
* **`detect:ifNone:`** - Evaluate aBlock with each of the receiver's elements as the argument until aBlock evaluates to true. Answer the first element for which aBlock evaluates to true, or answer the value in none block.

  For example:

  ```smalltalk
  "Return ('defaultKey' -> 'defaultValue')."
  { ('key' -> 'value').
    ('key2' -> 'value2') } asDictionary detect: [ :key :value | 
   key = 'key3' ] ifNone: [ 'defaultKey' -> 'defaultValue'].
  ```
* **`do:`** - Evaluate the given block for each element of the receiver.

  Each element is an association, so the block should accept two arguments, the key and the value.

  For example:

  ```smalltalk
  {('key' -> 'value'). ('key2' -> 'value2')} asDictionary do: [:key :value | Console print: 'key: ', key, ' value: ', value. Console cr].
  ```
* **`keysDo:`** - Pass each key in the dictionary to aBlock.

  For example:

  ```smalltalk
  dict := ('x' -> 'aaa'). ('y' -> 'bbb'). } asDictionary.
  ksn := 'k:'.
  dict keysDo: [ :ky | ksn := ksn + ky ]. "ksn = 'k:xy"
  ```
* **`reject:`** - Answer a new dictionary containing the key/value pairs for which aBlock returns false. aBlock only receives the value part of the pairs.

  For example:

  ```smalltalk
  dict := { ('x' -> 'aaa'). ('y' -> 'bbb'). ('z' -> 'ccc') } asDictionary.
  dict2 := dict reject: [ :val | val = 'aaa' ].
  dict2 associations. "{ ('y' -> 'bbb'). ('z' -> 'ccc') }"
  ```
* **`select:`** - Answer a new dictionary containing the key/value pairs for which aBlock returns true. aBlock only receives the value part of the pairs.

  For example:

  ```smalltalk
  dict := { ('x' -> 'aaa'). ('y' -> 'bbb'). ('z' -> 'ccc') } asDictionary.
  dict2 := dict select: [ :val | val = 'aaa' ].
  dict2 associations. "{ ('x' -> 'aaa') }"
  ```
* **`valuesCollect:`** - Answer a new dictionary where the keys are the same and the values are obtained by passing each value to aBlock and collecting the return values.

  For example:

  ```smalltalk
  dict := { ('x' -> 'aaa'). ('y' -> 'bbb'). } asDictionary.
  dict2 := dict valuesCollect: [ :val | val + '_' ].
  dict2 associations. "{ ('x' -> 'aaa_'). ('y' -> 'bbb_') }"
  ```
* **`valuesDo:`** - Pass each value in the dictionary to aBlock.

  For example:

  ```smalltalk
  dict := { ('x' -> 'aaa'). ('y' -> 'bbb'). } asDictionary.
  vsn := 'v:'.
  dict valuesDo: [ :val | vsn := vsn + val ]. "vsn = 'v:aaabbb'"
  ```

#### Category: removing

* **`remove:`** - Remove anAssociation’s key from the dictionary.

  For example:

  ```smalltalk
  dict := { ('x' -> 'aaa'). ('y' -> 'bbb'). ('z' -> 'ccc') } asDictionary.
  dict remove: ('y' -> 'bbb').
  "dict = { ('x' -> 'aaa'). ('z' -> 'ccc') }"
  dict remove: ('z' -> 'bbb').
  "dict = { ('x' -> 'aaa') }"
  ```
* **`remove:ifAbsent:`** - Remove anAssociation’s key from the dictionary, if absent call aBlock with the association.

  For example:

  ```smalltalk
  dict := ('x' -> 'aaa'). ('y' -> 'bbb') } asDictionary.
  dz := dict remove: ('z' -> 'bbb') ifAbsent: [ :asn | asn ]. "dz = ('z' -> 'bbb')"
  ```
* **`removeAllKeys:`** - Remove all the keys in keys, without raising any errors.

  For example:

  ```smalltalk
  dict := { ('x' -> 'aaa'). ('y' -> 'bbb'). ('z' -> 'ccc') } asDictionary.
  dict removeAllKeys: { 'z'. 'r'. 'y' } asList.
  dict associations. "{ ('x' -> 'aaa') }"
  ```
* **`removeAllKeys:ifAbsent:`** - Remove all the keys in keys, passing the missing keys as parameters to aBlock as they’re encountered.

  For example:

  ```smalltalk
  dict := { ('x' -> 'aaa'). ('y' -> 'bbb'). ('z' -> 'ccc') } asDictionary.
  kl := 'k:'.
  kys := { 'z'. 'r'. 'y'. s } asList.
  dict removeAllKeys: kys ifAbsent: [ :ky | kl := kl + ky ]. "kl = 'k:rs'"
  dict associations. "{ ('x' -> 'aaa') }"
  ```
* **`removeKey:`** - Remove the association for the given key.
* **`removeKey:ifAbsent:`** - Remove the association for the given key, if absent call aBlock with the key.

  For example:

  ```smalltalk
  dict := ('x' -> 'aaa'). ('y' -> 'bbb') } asDictionary.
  dz := dict removeKey: 'z' ifAbsent: [ :k | k ]. "dz = 'z'"
  ```

#### Category: testing

* **`includes:`** - Answer whether the receiver contains anObject as one of its values.
* **`includesAssociation:`** - Answer whether the receiver contains the key which is anAssociation’s key and its value is anAssociation’s value.
* **`includesKey:`** - Answer true if the receiver includes the given key.

  For example:

  ```smalltalk
  x := {('key' -> 'value'). ('key2' -> 'value2')} asDictionary .
  (x includesKey: 'key') = true.
  (x includesKey: 'key3') ifFalse: [ 
    x at: 'key3' put: 'a-default-value' ].
  (x at: 'key3') = 'a-default-value'.
  ```
* **`occurrencesOf:`** - Answer the number of occurrences of aValue as one of the receiver’s values.

  For example:

  ```smalltalk
  dict := { ('x' -> 'aaa'). ('y' -> 'bbb'). ('z' -> 'aaa') } asDictionary.
  num := dict occurrencesOf: 'y' "num = 0"
  num := dict occurrencesOf: 'aaa' "num = 2"
  ```

## Class: JSONReader

### Introduction

**Environment: `container`**

This is a class to read JSON into Mindscript objects.

For example:

```smalltalk
"the following example creates an array from a JSON expression:"
JSONReader fromString: ' [ 1,2,3 ] '.
"The next example creates a dictionary (with 'x' and 'y' keys):"
JSONReader fromString: ' { "x" : 1, "y" : 2 } '.
```

### Class Method

#### Category: convenience

* **`fromString:`** - Read a JSON string and return a Mindscript object.

  Return `nil` if the string is empty.

## Class: ProtoObject

### Introduction

**Environment: `container`**

ProtoObject establishes minimal behavior required of any object in Engine.

ProtoObject has no instance variables, nor should any be added.

One of the most important methods of ProtoObject is subclass:, which is used to create new classes.

```smalltalk
Object subclass: #MyClass
    instanceVariableNames: 'a b c'
    classVariableNames: 'd e f'
    package: 'MyPackage'
```

And for each object, they have the following default attributes that are implmented in ProtoObject:

* `name` the name of the object
* `class` the class of the object
* `comment` the comment of the object

### Instance Method

#### Category: accessing

* **`className`** - Answer the class name of the object.

  For example:

  ```smalltalk
  12 className = 'Integer'.
  'a' classname = 'String'.
  {} className = 'Array'.
  [] className = 'BlockClosure'
  ```
* **`nestedAt:`** - answer the element associated with the given nested keys.

  The keys are an array of strings to represent recursive keys in nested dictionaries.

  For example, let's say object `x` has attribute `a`, which is another object has an attribute `b`, then you can get the value of `b` like this:

  ```smalltalk
  x := {('a' -> {('b' -> 10)})} asDictionary.
  (x nestedAt: {'a'. 'b'}) = 10.
  ```

  For an array or a list, its attributes are indexes of them basing on 1.

  If the key is not found, return nil.
* **`nestedAt:ifAbsent:`** - answer the element associated with the given key.

  The keys are an array of strings to represent recursive keys in nested dictionaries.

  For example, let's say object `x` has attribute `a`, which is another object has an attribute `b`, then you can get the value of `b` with default value `0` like this:

  ```smalltalk
  x := {('a' -> {('b' -> 10)})} asDictionary.
  (x nestedAt: {'a'. 'b'}  ifAbsent: 0) = 10.
  (x nestedAt: {'a'. 'c'}  ifAbsent: [1 + 1]) = 2.
  y := {{('a' -> 10)} asDictionary }.
  (y nestedAt: {1. 'a'}) = 10.
  ```

  For an array or a list, its attributes are indexes of them basing on 1.

  If the key is not found, then return the value in default-value, which can be:

  * a code block or
  * a value.

#### Category: combining

* **`,`** - Concatenate two objects.
* **`->`** - answer an Association between self and an object.

  For example:

  ```smalltalk
  ('key' -> 'value').
  ```

#### Category: comparing

* **`!=`** - Primitive. This answers whether the receiver and the argument are not equal.
* **`=`** - Primitive. This answers whether the receiver and the argument are equal.
* **`==`** - Primitive. This answers whether the receiver and the argument are the same object (have the same object pointer).

#### Category: converting

* **`asArray`** - Answer an array to represent an object.

  For example:

  ```smalltalk
  array := 12 asArray. "returns '12'"
  array := 12.3 asArray. "returns {'12.3'}"
  array := {'a'} asArray. "returns {'a'}"
  ```
* **`asDictionary`** - answer a Dictionary by converting current object.
* **`asJson`** - Convert the Mindscript object to JSON string.

  For example:

  ```smalltalk
  "obj is a json string '[ 1, 2, 3 ]'"
  obj := {1. 2. 3} asJson.
  " obj2 is a json string '{ "x": 1,"y": 2 }'"
  obj2 := {('x' -> 1). ('y' -> 2)} asJson.
  ```
* **`asString`** - Converts an object into a string.

  For example:

  ```smalltalk
  str := 12 asString. "returns '12'"
  str := 12.3 asString. "returns '12.3'"
  ```

#### Category: instance creation

* **`new`** - answer a new instance of the receiver's class.

#### Category: testing

* **`ifNil:`** - answer the result of evaluating the given block if the receiver is nil.

  For example:

  ```smalltalk
  a := nil.
  a ifNil: [ a := 3 ].
  "Now a is equal to 3."

  a ifNil: [ a := 4 ].
  "Now a is still equal to 3."
  ```
* **`ifNil:ifNotNil:`** - If the receiver is not nil, pass it as argument to the ifNotNilBlock block. else execute the nilBlock block.

  For example:

  ```smalltalk
  a := 1.
  a ifNil: [ a := 3 ] ifNotNil: [ a := 4 ].

  "Now a is equal to 4."
  ```
* **`ifNotNil:`** - answer the result of evaluating the given block if the receiver is not nil.

  For example:

  ```smalltalk
  a := nil.
  a ifNotNil: [ a := 3 ].
  "Now a is equal to nil."

  a := 3.
  a ifNotNil: [ a := 4 ].
  "Now a is still equal to 4."
  ```
* **`ifNotNil:ifNil:`** - If the receiver is not nil, pass it as argument to the ifNotNilBlock block. else execute the nilBlock block.

  For example:

  ```smalltalk
  a := nil.
  a ifNotNil: [ a := 3 ] ifNil: [ a := 4 ].

  "Now a is equal to 4."
  ```
* **`isDefined`** - Whether an object is an UndefinedObject.
* **`isSequenceable`** - Answer whether the receiver can be accessed by a numeric index with #at:/#at:put:.

## Class: Random

### Introduction

**Environment: `container`**

I can generate a random number.

For example, to generate a random number between 0 and 6:

```smalltalk
" x is a random number between 0 and 6."
x := Random between: 0 and: 6.
```

### Class Method

#### Category: convenience

* **`between:and:`** - Generate a random number between a range.

  For example, to generate a random number between 0 and 6:

  ```smalltalk
  " x is a random number between 0 and 6."
  x := Random between: 0 and: 6.
  ```

## Class: Talk

### Introduction

**Environment: `container`**

My singleton is a central entry point to the system.

I can sleep for 3 seconds by `Talk sleepForSeconds: 3`.

### Class Method

#### Category: system

* **`sleepForSeconds:`** - sleep for several seconds.

  For example:

  ```smalltalk
  "Sleep 0.1s"
  Talk sleepForSeconds: 0.1
  ```

## Class: UndefinedObject

### Introduction

**Environment: `container`**

I describe the behavior of an undefined variable.

You can determine whether a variable has been defined or not by sending the message `isDefined` to any object. If the variable is undefined, you can expect a `false` response to that message.

It's important to make sure that all variables are properly initialized before they are used, to avoid errors and unexpected behavior in your program.

```smalltalk
b := 10.
"As a is not defined before, the following code block will not be evaluated."
a isDefined ifTrue: [ b := b + 1].
"b is still 10 as a is undefined."
a := 1.
"After a is defined."
a isDefined ifTrue: [ b := b + 1].
"Now b is 11."
```

This feature is extremely useful when establishing rules for a specific subject.

When a variable is defined within a subject, it can be used in another subject within the same conversation, assuming it was defined earlier.

This demonstrates that variables can be accessed at the conversation level.

### Instance Method

#### Category: testing

* **`isDefined`** - Whether an object is an UndefinedObject.
