How to set a default value to a map container in argument validation?

14 visualizaciones (últimos 30 días)
I'm validating a bunch of arguments in class properties. Seems quite straightfoward to set a deatault for double, integer and string datatypes.
classdef newClass < handle
properties
someStr (1,:) string = "myStr"
someNum (1,1) double = 3.1415
end
But what is the right way to do this for a map container? Because when I add this line for a map container:
someDict containers.Map
I see the following warning:

Respuesta aceptada

Steven Lord
Steven Lord el 30 de Mzo. de 2023
Movida: Walter Roberson el 4 de Abr. de 2023
Because each function call is independent I'd expect you wouldn't have the same issue with a handle object in a function's arguments block that you would with a class's properties block. Indeed, this little experiment supports my expectation. If the default value for dict was only created once the second call to the function should have listed both oldMissingValue and myKey as keys of the dict variable.
listOfKeys = example1936099_arg(42, "myKey")
listOfKeys = 1×1 cell array
{'myKey'}
listOfKeys = example1936099_arg(-999, "oldMissingValue")
listOfKeys = 1×1 cell array
{'oldMissingValue'}
listOfKeys = example1936099_arg()
listOfKeys = 1×1 cell array
{'myStr'}
function listOfKeys = example1936099_arg(value, name, dict)
arguments
value (1, 1) double = pi;
name (1, :) string = "myStr";
dict containers.Map = containers.Map;
end
dict(name) = value;
listOfKeys = keys(dict);
end
  1 comentario
Anup Kanale
Anup Kanale el 4 de Abr. de 2023
Movida: Walter Roberson el 4 de Abr. de 2023
Thank you Steven, this answers my question! If you could move this to Answer, I'll accept it.

Iniciar sesión para comentar.

Más respuestas (2)

Walter Roberson
Walter Roberson el 27 de Mzo. de 2023
test = containers.Map
test = Map with properties: Count: 0 KeyType: char ValueType: any
isa(test, 'handle')
ans = logical
1
Therefore if you were to pass in a container.Map to the constructor and copy what was received into a property, then the container would end up being shared with any other uses of the container.
To get around this, to get a private container.Map, you need to create the container.Map in the constructor (and make the property private and do not create any methods that can allow people to get at the container.Map). Or you could somehow clone the incoming container.Map (the class does not provide a method for copying / cloning though.)
If you want the container.Map to be shared then mark the property as Constant .
  6 comentarios
Anup Kanale
Anup Kanale el 28 de Mzo. de 2023
I want a private copy of the container. But my bad, your and @Steven Lord's answers made me realize that I am probably mixing up two different issues in my head! The first one is shared vs private copy of the container.
The second issue, and what I originally meant to ask, was how do I go about setting a default value for a container in the argument validation block (it makes sense in my script to move the container downstream from class property to a method)
function returnVar=myFunc(someNum, someStr, someDict)
arguments
someNum (1,1) double = 3.1415
someStr (1,:) string = "myStr"
someDict containers.Map = %?__default_value__?
end
end
PS: For the future viewer's benefit, please let me know if I should modify this question in place, or start a new thread instead.
Walter Roberson
Walter Roberson el 30 de Mzo. de 2023
Sorry, I do not have experience with using arguments blocks.

Iniciar sesión para comentar.


Steven Lord
Steven Lord el 27 de Mzo. de 2023
Consider the two classes attached to this answer. The class class1936099_A defines someDict to contain a containers.Map in the properties section of the class definition. The class class1936099_B assigns someDict a containers.Map in the constructor.
obj1 = class1936099_A;
obj2 = class1936099_A;
Neither obj1 nor obj2 have 'a' as a key in their someDict property.
[isKey(obj1.someDict, 'a'), isKey(obj2.someDict, 'a')]
ans = 1×2 logical array
0 0
Let's associate 'a' with 42 in obj1's property. What does obj2's property associate 'a' with now?
obj1.someDict('a') = 42;
obj2.someDict('a')
ans = 42
Let's try the same with class1936099_B.
obj3 = class1936099_B;
obj4 = class1936099_B;
[isKey(obj3.someDict, 'a'), isKey(obj4.someDict, 'a')]
ans = 1×2 logical array
0 0
obj3.someDict('a') = 42;
obj4.someDict('a')
Error using indexing
The specified key is not present in this container.
obj1 and obj2 have handles to the same containers.Map object. obj3 and obj4 have handles to different objects.

Categorías

Más información sobre Loops and Conditional Statements en Help Center y File Exchange.

Productos


Versión

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by