Observing State
Observe statement is used to capture values from the state and sets it to a value.
observe map <- ModMutate.num:
If an observe statement ends with an ‘:’ sign then it can have a body in which the value that has been observed can be used. If a variable is not declared in advance the value is lost after the observe statement.
Multiple targets and values can be listed in a single statement, e.g.
observe name, symbol, value <- Mod.name, Mod.symbol, Sender.Mod.value
Mutating State
Mutate statement is used to set a module value to the state.
mutate n -> ModMutate.State.check
In this case the the value in ‘n’ is set to the check field of the persistent state.
mutate num <- ModMutate.State.num:
If a mutate statement ends with a ‘:’ then the statement can have a context block. In the case of a mutate statement with a context the final value of num
after execution of the block is set back into the persistent state at the end of the mutation context. num
can’t be a variable name that’s already declared and it’s local to the mutate block.
As with observe
, mutate accepts multiple targets & values in a statement. Nesting is also allowed, so mutating values inside mutate block is possible.
Observing and Mutating Complex Values using disperse
and gather
Coco takes care to avoid expensive operations like transferring a large amount of data from the storage (state). E.g., if we want to only alter a single value in the map, there’s no need to load a complete map and store it back.
If we actually want to transfer a complete array, map or a class from the storage into memory, we need to explicitly prepend the assignment or append statement with gather
keyword, and if we’re storing the data from memory into storage, we need to prepend disperse
.
coco ModMutate
state persistent:
num Map[String]U64
check U64
endpoint deploy Init():
pass
endpoint invoke persistent Sum(num1 U64, str String):
mutate num <- ModMutate.State.num:
num[str] += num1
endpoint invoke Num() -> (output Map[String]U64):
observe output <- ModMutate.State.num
endpoint invoke Numplusone(str String) -> (output U64):
observe map <- ModMutate.State.num:
output = map[str] + 1
endpoint invoke persistent SetCheck(n U64):
mutate n -> ModMutate.State.check
coco Complex
state persistent:
Operators Map[U64]Operator
class Operator:
field Identifier String
field Guardians []String
endpoint deploy Init(moid String):
mutate operators <- atomic.Operators:
disperse operators[0] <- Operator{
Identifier: moid,
Guardians: make([]String, 0),
}
endpoint invoke Op0() -> (op Operator):
memory o Operator
observe operators <- atomic.Operators:
gather o <- operators[0]
op = o