# 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](/the-structure/values.md). 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](/the-structure/values.md)
* [Strings (Keys)](/the-structure/values/string.md)
* [Schema for Objects](/schema-definition-language/data-types/object.md)
* [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)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.internetobject.org/the-structure/values/object.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
