# \`Dict.get\_ptr()\` method: Suitable/permanent replacement for application code?

**URL:** <https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436>\
**Category:** Language Design\
**Tags:** mojo-compiler\
**Created:** [May 12, 2025, 1:24pm UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436 "2025-05-12T13:24:37Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![EzRyder](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/ezryder/32/133_2.png) [@EzRyder](https://forum.modular.com/u/EzRyder)\
**Post date:** [May 12, 2025, 1:24pm UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/1 "2025-05-12T13:24:37Z")

</div>

What replaces public method `some_dict.get_ptr(key)`?  
I see a note in the commit, “This eliminates the extraneous `get_ptr()` method which is unnecessary now. `_find_ref()` is enough.”  
By convention, the leading underscore signifies a private method that may change in the future, correct? Removal of get\_ptr breaks my code in several critical places, so I’d like a fix that does not rely on another interim solution. **Essentially, how do I access the actual objects stored in a dictionary (i.e. not a copy)?** Thanks!  
Discord post: [Discord](https://discord.com/channels/1087530497313357884/1224434323193594059/1371343242922295316)  
Github commit: [[mojo-stdlib] Simplify some code in dict.mojo and remove fixmes · modular/modular@1e12d81 · GitHub](https://github.com/modular/modular/commit/1e12d811fb9c38d0c1620be88f47bfea810e8003)

---

<div class="post-metadata">

**Author:** ![gryznar](https://avatars.discourse-cdn.com/v4/letter/g/e5b9ba/32.png) [@gryznar](https://forum.modular.com/u/gryznar)\
**Post date:** [May 12, 2025, 2:29pm UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/2 "2025-05-12T14:29:51Z")

</div>

I think, that it should be added that you want to obtatn reference to an object, no its copy (performance?) if I understand corrextly

---

<div class="post-metadata">

**Author:** ![EzRyder](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/ezryder/32/133_2.png) [@EzRyder](https://forum.modular.com/u/EzRyder)\
**Post date:** [May 12, 2025, 2:43pm UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/3 "2025-05-12T14:43:14Z")

</div>

Exactly!

> Essentially, how do I access the actual objects stored in a dictionary (i.e. not a copy)?

Here’s a similar issue with a (temporary) solution using `get_ptr` method.

> [@Help on invalid use of mutating method on rvalue](https://forum.modular.com/t/help-on-invalid-use-of-mutating-method-on-rvalue/1274/2):
>
> I’m not sure exactly what is the cause here, hopefully someone else can elaborate on that. I think that one of Dict.\_\_getitem\_\_ or List.\_\_getitem\_\_ is actually creating a copy of the Client, which is the rvalue that the the message refers to. Since the rvalue isn’t bound to anything, mutating it doesn’t do anything, and that’s an error (I think my terminology here is a bit messy). To fix it you just need to get a pointer to the dictionary value, for example: d01.get\_ptr("ClientA").value()[][…

---

<div class="post-metadata">

**Author:** ![EzRyder](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/ezryder/32/133_2.png) [@EzRyder](https://forum.modular.com/u/EzRyder)\
**Post date:** [May 12, 2025, 4:30pm UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/4 "2025-05-12T16:30:23Z")

</div>

> [@EzRyder](#):
>
> \_find\_ref

Looking at `dict.mojo` on GitHub, it appears that `fn find`, `fn setdefault`, and `fn __getitem__ ` now return a **reference** to a value stored in a dictionary. This is a change from previous behaviour, correct? Specifically, does `fn __getitem__ ` no longer returns a copy of the value, but a reference? I have not experimented to confirm this yet.  
dict.mojo: [modular/mojo/stdlib/stdlib/collections/dict.mojo at 1e12d811fb9c38d0c1620be88f47bfea810e8003 · modular/modular · GitHub](https://github.com/modular/modular/blob/1e12d811fb9c38d0c1620be88f47bfea810e8003/mojo/stdlib/stdlib/collections/dict.mojo)

```mojo
struct Dict[...]:
    fn _find_ref(
        ref self, key: K
    ) raises -> ref [self._entries[0].value().value] Self.V:
        """Find a value in the dictionary by key.

        Args:
            key: The key to search for in the dictionary.

        Returns:
            An optional value containing a reference to the value if it is
            present, otherwise an empty Optional.
        """

```

---

<div class="post-metadata">

**Author:** ![melodyogonna](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/melodyogonna/32/33_2.png) [@melodyogonna](https://forum.modular.com/u/melodyogonna)\
**Post date:** [May 12, 2025, 7:55pm UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/5 "2025-05-12T19:55:11Z")

</div>

Yes this is a reference

---

<div class="post-metadata">

**Author:** ![EzRyder](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/ezryder/32/133_2.png) [@EzRyder](https://forum.modular.com/u/EzRyder)\
**Post date:** [May 13, 2025, 12:57am UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/6 "2025-05-13T00:57:46Z")

</div>

I need a reference to ‘bar’ from the Dict, not a copy. Public method ‘fn get\_ptr’ provided this access to the object in the Dict.

```mojo
fn main():
    foo_dict = Dict[String, Int]()
    foo_dict["bar"] = 1

    try:
        print("1.1) foo_dict['bar'] =", foo_dict["bar"]) # 1 OK

        foo_dict["bar"] += 3
        print("1.2) foo_dict['bar'] =", foo_dict["bar"]) # 4 OK

        # I need a reference to 'bar' from the Dict, not a copy.
        # 'get_ptr' provided this access to the object in the Dict.
        # Below, 'bar' is a copy of foo_dict["bar"].
        bar = foo_dict["bar"]
        bar += 5
        print("1.3) bar =", bar)
        print("1.4) foo_dict['bar'] =", foo_dict["bar"], " <-- KO") # 4 KO (should be 9)
    except e:
        pass

```

**Output:**

```txt
1.1) foo_dict['bar'] = 1
1.2) foo_dict['bar'] = 4
1.3) bar = 9
1.4) foo_dict['bar'] = 4 <-- KO

```

---

<div class="post-metadata">

**Author:** ![EzRyder](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/ezryder/32/133_2.png) [@EzRyder](https://forum.modular.com/u/EzRyder)\
**Post date:** [May 13, 2025, 1:15am UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/7 "2025-05-13T01:15:46Z")

</div>

> [@EzRyder](#):
>
> ```auto
> Returns:
> An optional value containing a reference to the value if it is
> present, otherwise an empty Optional.
> 
> ```

The comment for `fn _find_ref` in `struct Dict` says it returns an `Optional`, but evidence suggests otherwise. **I definitely need some help here.** TIA!

---

<div class="post-metadata">

**Author:** ![christoph\_schlumpf](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/christoph_schlumpf/32/274_2.png) [@christoph\_schlumpf](https://forum.modular.com/u/christoph_schlumpf)\
**Post date:** [May 13, 2025, 7:02pm UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/8 "2025-05-13T19:02:53Z")

</div>

The assignment `bar = foo_dict["bar"]` implicitly copies the referenced value into `bar`. So `bar += 5` only modifies the copied value.

---

<div class="post-metadata">

**Author:** ![clattner](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/clattner/32/201_2.png) [@clattner](https://forum.modular.com/u/clattner)\
**Post date:** [May 14, 2025, 1:23am UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/9 "2025-05-14T01:23:08Z")

</div>

I’m sorry for breaking you! Instead of `d01.get_ptr("ClientA").value()` you should be able to just use `d01["ClientA"]` in a try block.

---

<div class="post-metadata">

**Author:** ![EzRyder](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/ezryder/32/133_2.png) [@EzRyder](https://forum.modular.com/u/EzRyder)\
**Post date:** [May 14, 2025, 2:10am UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/10 "2025-05-14T02:10:56Z")

</div>

Hi Chris! I’m not sure it’s returning a reference. That’s why I need `fn get_ptr` or equivalent in the first place. In the repro below, I expect that the value at `1.3)` should be 9. What am I missing?  
@clattner

```mojo
@value
struct Foo:
    var value: Int

    fn add(mut self, x: Int):
        self.value += x

alias foos = Dict[String, Foo]

fn main():
    foos = foos()
    foos["bar"] = Foo(1)

    try:
        print("1.1) value =", foos["bar"].value) # 1 OK

        foos["bar"].add(3)
        print("1.2) value =", foos["bar"].value) # 4 OK

        # Below, 'bar' is a copy of foos["bar"].
        bar = foos["bar"]
        bar.add(5)
        print(
            "1.3) value =", foos["bar"].value, " <-- KO"
        ) # 4 KO (should be 9)

    except e:
        pass

```

**Output:**

```txt
1.1) value = 1
1.2) value = 4
1.3) value = 4 <-- KO

```

---

<div class="post-metadata">

**Author:** ![xtxtxtxtxtx](https://avatars.discourse-cdn.com/v4/letter/x/dec6dc/32.png) [@xtxtxtxtxtx](https://forum.modular.com/u/xtxtxtxtxtx)\
**Post date:** [May 14, 2025, 4:32am UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/11 "2025-05-14T04:32:46Z")

</div>

```mojo
bar = foos["bar"]

```

This line copies `foos["bar"]`. You can see its returning refrence by doing this which correctly modifies the value.In mojo = copies the value not refrence if my understanding is correct.

```mojo
foos["bar"].add(5)

```

---

<div class="post-metadata">

**Author:** ![christoph\_schlumpf](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/christoph_schlumpf/32/274_2.png) [@christoph\_schlumpf](https://forum.modular.com/u/christoph_schlumpf)\
**Post date:** [May 14, 2025, 6:00am UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/12 "2025-05-14T06:00:59Z")

</div>

If you want to „reference“ the original value from another `var` without copying it, you can use a Pointer: `bar = Pointer(to=foos[”bar”])`.  
To modify the original value: `bar[].add(5)`

---

<div class="post-metadata">

**Author:** ![xtxtxtxtxtx](https://avatars.discourse-cdn.com/v4/letter/x/dec6dc/32.png) [@xtxtxtxtxtx](https://forum.modular.com/u/xtxtxtxtxtx)\
**Post date:** [May 14, 2025, 6:17am UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/13 "2025-05-14T06:17:36Z")

</div>

That will probably give immutable pointer. If you want mutable pointer you may need to do this

```mojo
bar = UnsafePointer(to=foos["bar"]).origin_cast[mut=True]()
bar[].add(5)

```

---

<div class="post-metadata">

**Author:** ![gryznar](https://avatars.discourse-cdn.com/v4/letter/g/e5b9ba/32.png) [@gryznar](https://forum.modular.com/u/gryznar)\
**Post date:** [May 14, 2025, 12:45pm UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/14 "2025-05-14T12:45:25Z")

</div>

@clattner shouldn’t ` __getitem__ ` in `Dict` just return a ref by default? With autoderef this would be more performant. IMO there is no need to return copy of data here and not the data itself and this is more natural to operate on original data

---

<div class="post-metadata">

**Author:** ![EzRyder](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/ezryder/32/133_2.png) [@EzRyder](https://forum.modular.com/u/EzRyder)\
**Post date:** [May 14, 2025, 1:21pm UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/15 "2025-05-14T13:21:37Z")

</div>

Referring to the code below, I expect/need for each `add` operation to affect the same object in memory, regardless of whether it’s a variable, stored in a List/Dict, or retrieved from a List/Dict and assigned to a variable. No copies, mutable by default.  
I use a Dict to store complex structs that, when retrieved, must point to the same object because its internal state changes often as the application runs. This is a fundamental dependency, with memory and performance/speed secondary considerations (for now 😀).

```mojo
from collections import Dict
from testing import assert_true

@value
struct Foo:
    var value: Int

    fn add(mut self, x: Int):
        self.value += x

alias DictFoos = Dict[String, Foo]
alias ListFoos = List[Foo]
alias A = 1
alias B = 3
alias C = 5

fn main():
    foo = Foo(1)

    dict01 = DictFoos()
    dict01["bar"] = foo

    list01 = ListFoos()
    list01.append(foo)

    try:
        # Initial values
        assert_true(foo.value == A, "Foo")
        assert_true(dict01["bar"].value == A, "Dict")
        assert_true(list01[0].value == A, "List")

        foo.add(B)
        # dict01["bar"].add(B) # Equivalent
        # list01[0].add(B) # Equivalent

        expected = A + B
        print("1.1) expected =", expected)
        print("1.2) foo value =", foo.value)
        print("1.3) dict value =", dict01["bar"].value, "KO")
        print("1.4) list value =", list01[0].value, "KO")

        assert_true(foo.value == expected, "Foo_1")
        assert_true(dict01["bar"].value == expected, "Dict_1")
        assert_true(list01[0].value == expected, "List_1")

    except e:
        print(e)

```

**Output:**

```txt
1.1) expected = 4
1.2) foo value = 4
1.3) dict value = 1 KO
1.4) list value = 1 KO

```

---

<div class="post-metadata">

**Author:** ![xtxtxtxtxtx](https://avatars.discourse-cdn.com/v4/letter/x/dec6dc/32.png) [@xtxtxtxtxtx](https://forum.modular.com/u/xtxtxtxtxtx)\
**Post date:** [May 14, 2025, 1:41pm UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/16 "2025-05-14T13:41:53Z")

</div>

Something like this maybe solution for you

```mojo
from collections import Dict
from testing import assert_true
from memory import UnsafePointer

@value
struct Foo:
    var value: Int

    fn add(mut self, x: Int):
        self.value += x

alias DictFoos = Dict[String, UnsafePointer[Foo]]
alias A = 1
alias B = 3
alias C = 5

fn main():
    var foo = Foo(1)

    var dict01 = DictFoos()
    dict01["bar"] = UnsafePointer(to=foo)

    try:
        # Initial values
        assert_true(foo.value == A, "Foo")
        assert_true(dict01["bar"][].value == A, "Dict")

        foo.add(B)
        # dict01["bar"].add(B) # Equivalent

        alias expected = A + B
        print("1.1) expected =", expected)
        print("1.2) foo value =", foo.value)
        print("1.3) dict value =", dict01["bar"][].value)

        assert_true(foo.value == expected, "Foo_1")
        assert_true(dict01["bar"][].value == expected, "Dict_1")

    except e:
        print(e)

```

---

<div class="post-metadata">

**Author:** ![christoph\_schlumpf](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/christoph_schlumpf/32/274_2.png) [@christoph\_schlumpf](https://forum.modular.com/u/christoph_schlumpf)\
**Post date:** [May 14, 2025, 2:33pm UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/17 "2025-05-14T14:33:12Z")

</div>

` __getitem__ ` returns a `ref`. But assigning it to another `var` makes a copy (this is by design).

---

<div class="post-metadata">

**Author:** ![EzRyder](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/ezryder/32/133_2.png) [@EzRyder](https://forum.modular.com/u/EzRyder)\
**Post date:** [May 14, 2025, 4:39pm UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/18 "2025-05-14T16:39:05Z")

</div>

Per @christoph_schlumpf’s comment, is the recommended/safe approach to use an [ArcPointer](https://docs.modular.com/mojo/stdlib/memory/arc/ArcPointer) as shown in the code below? This way, even if variable `foo_ptr` goes out of scope and is destroyed, the Dict and List instances each contain a valid/usable pointer to the original `Foo` object.

```mojo
from collections import Dict
from testing import assert_true, assert_false
from memory import ArcPointer

@value
struct Foo:
    var value: Int

    fn add(mut self, x: Int):
        self.value += x

alias DictFoos = Dict[String, ArcPointer[Foo]]
alias ListFoos = List[ArcPointer[Foo]]
alias A = 1
alias B = 3
alias C = 5

fn main():
    foo_ptr = ArcPointer(Foo(1))
    foo = foo_ptr[] # Makes a copy of the `Foo object`

    dict01 = DictFoos()
    dict01["bar"] = foo_ptr

    list01 = ListFoos()
    list01.append(foo_ptr)

    try:
        # Initial values
        assert_true(foo.value == A, "Foo")
        assert_true(dict01["bar"][].value == A, "Dict")
        assert_true(list01[0][].value == A, "List")

        # 'foo' is a copy of the original object,
        # so 'add' affects only the variable 'foo'.
        foo.add(B)
        expected = A + B
        assert_true(foo.value == expected, "Foo_1")
        assert_false(dict01["bar"][].value == expected, "Dict_1")
        assert_false(list01[0][].value == expected, "List_1")

        print("---------------------------")
        print("1.0) foo.add(B)")
        print("1.1) expected =", expected)
        print("1.2) foo value =", foo.value, "copy, changed")
        print("1.3) dict value =", dict01["bar"][].value, "unchanged")
        print("1.4) list value =", list01[0][].value, "unchanged")

        # 'add' affects objects in both Dict and List.
        dict01["bar"][].add(B)
        assert_true(foo.value == expected, "Foo_2")
        assert_true(dict01["bar"][].value == expected, "Dict_2")
        assert_true(list01[0][].value == expected, "List_2")

        print("---------------------------")
        print("2.0) dict01['bar'][].add(B)")
        print("2.1) expected =", expected)
        print("2.2) foo value =", foo.value, "copy, unchanged")
        print("2.3) dict value =", dict01["bar"][].value, "changed")
        print("2.4) list value =", list01[0][].value, "changed")

        # 'add' affects objects in both Dict and List.
        list01[0][].add(C)
        expected = A + B + C
        assert_false(foo.value == expected, "Foo_3")
        assert_true(dict01["bar"][].value == expected, "Dict_3")
        assert_true(list01[0][].value == expected, "List_3")

        print("---------------------------")
        print("3.0) list01[0][].add(C)")
        print("3.1) expected =", expected)
        print("3.2) foo value =", foo.value, "copy, unchanged")
        print("3.3) dict value =", dict01["bar"][].value, "changed")
        print("3.4) list value =", list01[0][].value, "changed")

    except e:
        print(e)

```

**Output:**

```txt
1.0) foo.add(B)
1.1) expected = 4
1.2) foo value = 4 copy, changed
1.3) dict value = 1 unchanged
1.4) list value = 1 unchanged
---------------------------
2.0) dict01['bar'][].add(B)
2.1) expected = 4
2.2) foo value = 4 copy, unchanged
2.3) dict value = 4 changed
2.4) list value = 4 changed
---------------------------
3.0) list01[0][].add(C)
3.1) expected = 9
3.2) foo value = 4 copy, unchanged
3.3) dict value = 9 changed
3.4) list value = 9 changed

```

---

<div class="post-metadata">

**Author:** ![christoph\_schlumpf](https://sea1.discourse-cdn.com/flex001/user_avatar/forum.modular.com/christoph_schlumpf/32/274_2.png) [@christoph\_schlumpf](https://forum.modular.com/u/christoph_schlumpf)\
**Post date:** [May 15, 2025, 11:20am UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/19 "2025-05-15T11:20:56Z")

</div>

Hi @EzRyder ,  
Looks good to me. See [Intro to pointers | Modular](https://docs.modular.com/mojo/manual/pointers/#arcpointer)

---

<div class="post-metadata">

**Author:** ![samufi](https://avatars.discourse-cdn.com/v4/letter/s/d2c977/32.png) [@samufi](https://forum.modular.com/u/samufi)\
**Post date:** [May 26, 2025, 10:02pm UTC](https://forum.modular.com/t/dict-get-ptr-method-suitable-permanent-replacement-for-application-code/1436/20 "2025-05-26T22:02:50Z")

</div>

The reference (and hence the pointer) that we get this way is immutable (see [this issue](https://github.com/modular/modular/issues/4695)). First I thought this is just a missing `ref` keyword, but now I came to guess that returning a mutable ref could [cause confusion with ` __setitem__ `](https://github.com/modular/modular/issues/4705). If this is the case (and not trivial to fix) I think it would be great to still have some kind of `get_ptr`…
