Sorry the question might not be very clear, let me explain: I recently learnt that by using stable records that have a var member inside it, when that record is passed to functions, the inner var member is handled by motoko as a reference, and hence it is possible to update a stable var inside a function. By example:
// In my canister
stable let my_wrapped_var = { var inner = "foo"; };
updateMyVar(my_wrapped_var);
func updateMyVar(my_wrapped_var: MyWrappedVar) {
my_wrapped_var.inner := "bar"; // This updates the variable in stable memory
};
This example is quite simple, but I was experimenting doing a module like this for a TrieClass:
type WrappedRef<T> = { var ref: T; };
public func init<T>(t : T) : WrappedRef<T>{
{
var ref = t;
};
};
type Trie<K, V> = Trie.Trie<K, V>;
type Key<K> = Trie.Key<K>;
public class TrieClass<K, V>(
trie_: WrappedRef<Trie<K, V>>,
key_gen: (K) -> Key<K>,
key_eq: (K, K) -> Bool
) {
// Wrapping all Trie functions...
public func put(k: K, v: V) : ?V {
let (trie, old_v) = Trie.put(trie_.ref, key_gen(k), key_eq, v);
trie_.ref := trie;
old_v;
};
public func get(k: K) : ?V {
Trie.get(trie_.ref, key_gen(k), key_eq);
};
public func remove(k: K) : ?V {
let (trie, old_v) = Trie.remove(trie_.ref, key_gen(k), key_eq);
trie_.ref := trie;
old_v;
};
};
Then in my canister:
stable let trie_ref = WrappedRef.init(Trie.empty<Nat32, Text>());
let trie = TrieClass.TrieClass<Nat32, Text>(trie_ref, keyNat32, Nat32.equal);
// perform updates on the trie in OOP way, directly in stable memory!
trie.put(0, "hello");
doSomethingThatUpdateMyTrie(trie);
// etc.
Is there any inconvenient in doing this ?