Implementing setter functions

For mutable types, we may implement setters. The scope would include fields that can only ever be mutated. For our simulation project, suppose that we want to allow the client program to do some transformation of the heatmap and put it back to the object. We can support that use case easily, as shown in the following code snippet:

function heatmap!(
s::Simulation{N},
new_heatmap::AbstractArray{Float64, N}) where {N}
s.heatmap = new_heatmap
s.stats = (mean = mean(new_heatmap), std = std(new_heatmap))
return nothing
end

The setter function, heatmap!, accepts a Simulation object and a new heatmap array. Because the stats field contains the statistics of the underlying heatmap, we must maintain consistency within the object by recalculating the statistics and updating the field. Note that such a guarantee for consistency is only possible when we provide a setter function. Otherwise, the object would be in an inconsistent state if we ever to allow users to directly mutate the heatmap field in the object.

An additional benefit is that we can perform data validation in the setter function. For example, we can control the size of the map and throw an error when the size of the heatmap contains odd shapes:

function heatmap!(
s::Simulation{N},
new_heatmap::AbstractArray{Float64, N}) where {N}
if length(unique(size(new_heatmap))) != 1
error("All dimensions must have same size")
end
s.heatmap = new_heatmap
s.stats = (mean = mean(new_heatmap), std = std(new_heatmap))
return nothing
end

Here, we first determine the size of new_heatmap, which should be returned as a tuple. Then, we find out how many unique values are in this tuple. If there is only a single unique number in the tuple, then we know that the array is square, cubic, and so on. Otherwise, we just throw an error back to the caller.

Just like getter functions, setter functions serve as a public interface where the data of an object may be mutated. After we have both getter and setter functions, we can expect the caller to go through the interfaces. But the original fields can still be accessed directly. So, how do we stop that from happening? Let's explore that next.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.83.151