---
title: "Object References and Copies · RUAL Documentation"
description: "Objects are passed by reference: which blocks change the original, and when to take a shallow or deep copy."
canonical: https://docs.rual.nl/blueprints/object-references
language: en
---

# Object References and Copies

Objects on the canvas are passed by reference. Updating one can change what another block already read. This page shows when that happens and how to take a copy.

An object pin does not carry a snapshot of the object. It carries the object itself. Two blocks connected to the same object out-pin are looking at the same thing in memory, so a change made through one of them is visible to the other, including to blocks that already ran.

That is what makes flows cheap: a document of a few hundred fields is passed around without being copied on every hop. It is also the source of a specific class of bug, where a value changes underneath a block that looked at it earlier.

### Which blocks change the original

| Block | What it does with the input |
| --- | --- |
| [`object_update_fields`](https://docs.rual.nl/block-types/object/object_update_fields) | Applies the mutations and field pins **to the object you connected**, then outputs that same object. The original changes. |
| [`object_new_fields`](https://docs.rual.nl/block-types/object/object_new_fields) | Builds a fresh object from its in-pins. Nothing you connected is modified. |
| [`object_shallow_copy`](https://docs.rual.nl/block-types/object/object_shallow_copy) | Builds a new object with the same top-level keys. Nested objects and arrays are still shared with the original. |
| [`object_deep_copy`](https://docs.rual.nl/block-types/object/object_deep_copy) | Builds a new object with no shared references at any depth. The safest, and the most expensive. |

### Shallow copy versus deep copy

A shallow copy protects the top level only. Take a customer object with a nested `address`: after a shallow copy, setting `status` on the copy leaves the original alone, but setting `address.city` changes the original as well, because both objects point at the same nested address.

A deep copy rebuilds every level, so nothing is shared. It costs time and memory proportional to the size of the object, which is why the block's own description warns against widespread use. Reach for it when you genuinely need an independent snapshot, for example when you keep a "before" version of a document to compare against or to log.

```
original = {
  "name": "joe doe",
  "address": { "city": "Amsterdam" }
}

copy = shallow_copy(original)
copy.name = "sami b"          // original.name is still "joe doe"
copy.address.city = "Utrecht" // original.address.city is now "Utrecht" as well

copy = deep_copy(original)
copy.address.city = "Utrecht" // original.address.city stays "Amsterdam"
```

### Where this bites in practice

- **Keeping a before and after.** Reading a document, updating it in place, and then trying to log "what it was" gives you the new values twice. Deep-copy the document before the update if you want the old state.

- **Iterations.** Updating the object of the current item inside a loop mutates the entry in the array you are iterating over. That is fine when it is what you meant, and confusing when it is not.

- **Reusing a template object.** Building one base object and updating it per iteration leaves every reference pointing at the final state. Build a new object per iteration, or copy the template inside the loop.

- **Passing to a function.** A custom function that updates the object it received changes the caller's object too. Copy at the boundary if the function is meant to be a pure transformation.

### Storage documents follow the same rule

A document read from storage is an ordinary object on the canvas, so everything above applies to it. Writing to it does not write to storage: persisting still goes through mutations and [`function_update_document`](https://docs.rual.nl/block-types/storage/function_update_document_mutations), described in [Storages](https://docs.rual.nl/blueprints/storage). What in-place updates do change is what the rest of your flow sees.

### Next steps

### Frequently asked

**Does updating an object in RUAL change the original?**

It depends on the block. object_update_fields applies its changes to the object you connected and outputs that same object, so the original changes. object_new_fields builds a new object and leaves the input untouched.

**What is the difference between a shallow copy and a deep copy in RUAL?**

A shallow copy creates a new object with the same top-level keys, but nested objects and arrays are still shared with the original. A deep copy rebuilds every level, so nothing is shared. Deep copies cost time and memory proportional to the object size.

**How do I keep the old version of a document before updating it in RUAL?**

Take a deep copy before you apply the update. Updating in place changes the object every other block is holding, so without a copy the before and after values are the same.
