# Objects

Objects are a fundamental element in Internet Object documents, providing a clear and intuitive way to represent structured data.

An object is expressed as **a sequence of values and/or key/value pairs separated by commas** (`,` `U+002C`). For simplicity, clarity, and ease of reading, Internet Object supports two modes for objects:

* **Open Objects** — do not require curly braces and are allowed **only at the top level**.
* **Closed Objects** — are enclosed in `{}` and may appear at any level.

Objects may contain:

* **Sequential (unkeyed) values**
* **Inline keyed values** (`key: value`)
* **Any combination and ordering** of keyed and unkeyed values

All values in an object are accessed by **position** (0-based). If a value has a key, it may also be accessed by **key**—especially when a schema is applied.

🧩 **Design Note:** In the early stages of its design, Internet Object was envisioned as a compact, expressive serialization format focused on transmitting structured objects across the internet. The name “Internet Object” was born out of this **object-oriented serialization** model — structurally similar to formats like JSON.

As the format evolved, it adopted a **document-oriented approach**, enabling richer representation through sections, schemas, metadata, and stream-friendly constructs. However, the object remains the core unit of structure, and the compact syntax continues to reflect its original vision.

⚙️ **Implementation Note:** In many programming languages, the term `Object` refers to a built-in or base type. To avoid conflicts, libraries and parsers implementing Internet Object may use a distinct class or type name such as `InternetObject`. For example, in JavaScript:

```js
const obj = new InternetObject()
```

Here, `obj` is an instance of a class that represents an Internet Object — conforming fully to the object syntax and behavior defined in this specification.

## Syntax

### Closed Object

```ebnf
object         = "{" [ objectEntries ] "}"
objectEntries  = entry *( "," entry )

entry          = keyedValue | unkeyedValue
keyedValue     = key ":" value
unkeyedValue   = value

key            = string
value          = any valid Internet Object value
```

### Open Object

```ebnf
objectOpen = objectEntries
```

> Keys must be valid [strings](https://github.com/maniartech/InternetObject-specs/blob/gitbook/the-structure/string.md). Values must be valid [Internet Object values](https://docs.internetobject.org/the-structure/values). Keyed and unkeyed values can appear in any order.

## Structural Characters

| Symbol | Name                | Unicode  | Description                           |
| ------ | ------------------- | -------- | ------------------------------------- |
| `{`    | Open Curly Bracket  | `U+007B` | Begins a closed object                |
| `}`    | Close Curly Bracket | `U+007D` | Ends a closed object                  |
| `:`    | Colon               | `U+003A` | Separates keys from values            |
| `,`    | Comma               | `U+002C` | Separates values or key–value entries |

## Valid Forms

### Open Object with Unkeyed and Keyed Values (Any Order)

```ruby
name: John, Doe, 25
John, age: 25, gender: M
name: John, age: 25, gender: M, T
John Doe, 25, T
```

### Closed Object with Mixed Values

```ruby
{name: John, Doe, 25}
{John, age: 25, gender: M}
{name: John, age: 25, gender: M, T}
{John Doe, 25, T}
```

### Fully Keyed Object

```yaml
{
  name: John Doe,
  age: 25,
  gender: M,
  isActive: T
}
```

### Keys as Strings (Quoted Forms)

```yaml
{
  "name": John Doe,
  'isActive': T,
  address: {Bond Street, New York, NY}
}
```

### JSON-Compatible Object Example

The following Internet Object is also a valid JSON object:

```ruby
{"name": "John", "age": 30, "isActive": true}
```

> Keys are double-quoted strings and all values use standard JSON types. **Child objects must always be enclosed in curly braces `{}`.** Only the top-level object may use the open form. All nested or embedded objects must use **closed object syntax**.

## Invalid Forms

```ruby
# ✗ Missing commas between values
{name: John Doe 25}
{John age: 25 gender: M}
```

## Optional Behaviors

### Whitespace and Formatting

Whitespace is allowed and ignored:

```ruby
{ name : John , age : 25 }
```

### Empty Objects

```ruby
{}     # ✅ Valid
```

### Empty Values

Empty value positions (via `,,`) are valid:

```ruby
John Doe,,true,,{NY}
```

### Trailing Commas

Trailing commas are allowed and ignored:

```ruby
John, 25, T,,,,
```

## Comments

Comments are allowed between entries or alongside values:

```ruby
{
  name: John,     # name of person
  age: 25,        # years old
  isActive: T
}
```

> Comments must not appear inside string literals or values.

## Access Semantics

* All values are accessed by their **position** (0-based).
* If a key is provided, the value **may also be accessed via key**, especially when schema is applied.
* Keys do not affect the value's index position.
* Keys are optional but must be **well-formed strings**.

## Preservation of Structure

Internet Object preserves:

* Value order and keyed/unkeyed structure
* Whitespace (non-significant)
* Optional comments

It does **not** enforce:

* Key uniqueness
* Key-based access without schema
* Required presence of keys

## See Also

* [Values](https://docs.internetobject.org/the-structure/values)
* [Strings (Keys)](https://docs.internetobject.org/the-structure/values/string)
* [Schema for Objects](https://docs.internetobject.org/schema-definition-language/data-types/object)
* [Comments](https://github.com/maniartech/InternetObject-specs/blob/gitbook/the-structure/syntax/comments.md)
* [JSON Compatibility](https://github.com/maniartech/InternetObject-specs/blob/gitbook/json-compatibility.md)
