Set methods for two interdependent properties in class: how do I avoid infinite recursion?

11 visualizzazioni (ultimi 30 giorni)
I want to define a class where two properties depend on each other. This means that each set method should modify the other property accordingly.
Simplified example: let's say I define a class for a car, that contains its speed in different units:
classdef Car
properties
speed_km_h = 0;
speed_mph = 0;
end
methods
function obj = set.speed_km_h(obj, value)
obj.speed_km_h = value;
obj.speed_mph = value / 1.61;
end
function obj = set.speed_mph(obj, value)
obj.speed_mph = value;
obj.speed_km_h = value * 1.61;
end
end
end
Implemented like above, asigning a value to one of the properties results in an infinite recursion loop, since each set method calls the other one:
c = Car;
c.speed_km_h = 30;
Out of memory. The likely cause is an infinite recursion within the program.
What's the corrent way to implement this kind of functionality?
Some notes:
  • In the simple example above, having one of the values be a dependent property might be a better solution, but I'm asking explicitly about two properties that actually store these values seperatly in the object.
  • Defining the properties with AbortSet breaks the recursion and makes the example work, but only if the third setter in the recursion stack tries to set the same value as the original one. If e. g. one of the unit conversions were to introduce a rounding error, the recursion would happen again. There must be a more elegant way, right?
  4 Commenti
Matt J
Matt J il 7 Nov 2022
Modificato: Matt J il 7 Nov 2022
The appropriate recommendation depends on how they will be accessed (read or write) and how often in each case. If they will only be read-accessed often, then you may as well just compute both properties once in the constructor and make them Immutable. No need for set.property methods.
If they need to be write-accessed often, there is no benefit to storing them both. The same computations will be required to keep them consistent whether one of the properties is Dependent or not. In fact, it would be more benefical to have one property Dependent, because then only the concrete property needs to be updated in a write operation.
fi
fi il 9 Nov 2022
Can't argue with that logic, and I see now that a dependent property is probably also the correct way to go in my real case. Thanks!
Still though – I can't help but feel that in general, having two different setters that happen to call each other isn't a super far fetched scenario...

Accedi per commentare.

Risposta accettata

Matt J
Matt J il 7 Nov 2022
Modificato: Matt J il 7 Nov 2022
Here's a possible solution with both properties Dependent. It will avoid the infinite recursion, but as I said above, it's not clear to me that storing 2 versions of the same property is the wisest course.
classdef Car
properties
Speed_km_h = 0;
Speed_mph = 0;
end
properties (Dependent)
speed_km_h
speed_mph
end
methods
function obj = set.speed_km_h(obj, value)
obj.Speed_km_h = value;
obj.Speed_mph = value / 1.61;
end
function obj = set.speed_mph(obj, value)
obj.Speed_mph = value;
obj.Speed_km_h = value * 1.61;
end
function value = get.speed_km_h(obj)
value =obj.Speed_km_h;
end
function value = get.speed_mph(obj)
value =obj.Speed_mph;
end
end
end
end
  2 Commenti
fi
fi il 9 Nov 2022
That works, although it feels a bit like a workaround.
I guess there is just no elegant way to get this functionality and in most cases the answer is simply 'don't store redundant information'.
Thanks!

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Construct and Work with Object Arrays in Help Center e File Exchange

Prodotti

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by