Function parameters as switch/data pairs?

I have a function that takes at least one value, and currently a variable number of string arguments that are used as switches/flags. However, I would like to be able to have the function require that if 'a' is passed, then data 'A' is also passed. Is this possible?

7 Comments

Are you saying that if the string 'a' is one of the variable string arguments passed into the function, then the user must also supply A which is another string or a matrix or ..? What does your function signature currently look like, and how do you expect it to be used (with examples)?
Yeah, but you've got to write the argument validation logic...the tools of the trade include
doc varargin
doc narginchk
doc nargin
etc., ...
That's for traditional functions; I've not played w/ the o-oriented stuff enough to know if there are more automagic tools for validation or not. Too bad if not isn't something like the old VMS DCL command generator/parser...
Currently the signature (I believe, not as familiar with Matlab) is
function output = userDimensions( structA, cellArrayA, cellArrayB, cellArrayC, varargin )
Here, structA is a struct and ideally would be a required parameter, and the cellArray* parameters should be cell arrays of structs, and varargin handles the flags. I would expect this to be used perhaps like so:
result = userDimensions(someStruct, someArray, 'target');
Here, 'target' would be the string-type argument that signals to the function that it's supposed to perform a particular set of operations on someArray, using information from someStruct.
Another example:
result = userDimensions(someStruct, wrongArray, 'target');
Here, wrongArray is not the data structure that the 'target' operations is intended to operate on, either because it contains the wrong sort of data, or is the wrong size.
In your second example, how is the code supposed to know that wrongArray is not the data structure that the "target" operations is intended to operate on, given that there really isn't any difference between this example and the previous one?
Hmm. This is why I'd rather just tell the user in the description of the function to make sure they load certain data structures and then be able to use them by name within the function.
So does someArray correspond to cellArrayA, and wrongArray correspond to cellArrayB? If so, then you may want to follow the suggestions of the cyclist and dpb below. Else, the user would be responsible for choosing how to supply data to the function
result = userDimensions(someStruct, someArray, 'target');
or
result = userDimensions(someStruct, {}, wrongArray, 'target');
...wrongArray is not the data structure that the 'target' operations is intended to operate on, either because it contains the wrong sort of data, or is the wrong size.
...how is the code supposed to know that wrongArray is not the data structure that the "target" operations is intended to operate on, given that there really isn't any difference between this example and the previous one?...
Well, the latter is easy presuming that by in the "target" operation there's an implied required size. The other is somewhat more problematical, but probably the easiest way to solve it is to have an ID field in the structure that you can query to ascertain the type. Somewhat akin to the 'Type' property of the handle graphics objects.
get(gca,'type')
always returns the string 'axes'. Of course one never needs to query gca, but given a random handle that's just a floating point value, it's a useful thing to ask. Such a scheme could be implemented here to build a more-or-less polymorphic interface it seems.

Sign in to comment.

Answers (2)

You probably want to use the nargin function, which will tell you how many argument have been entered into the function.
For example, you could do something like
if (nargin > 2) && (nargin < 4)
disp('ERROR: If you enter 3 arguments, you must enter the 4th as well.')
return
end

3 Comments

I'd thought of that, but that would allow the user to enter an even number of flags, but not include any of the data.
dpb
dpb on 28 Jun 2014
Edited: dpb on 28 Jun 2014
nargin will count the data as an argument just as the parameters; they're all the same to it. The problem is you have to look at the value of the arguments and include the logic of what to do if each particular one is specified. If they all have to be parameter,value pairs, then you can start on checking for even and pairing up; if they can be just indicators standing alone then that's more effort as you see. (That's at least in part why I think TMW for logicals uses the syntax 'parameter',true|false for things like 'collectoutput' instead of the keyword 'collectoutput' meaning true and not being present in the list being false).
It seems to me that you need to pair this kind of logic with some other checking. For example, if there are an even number of objects, then check the 2nd, 4th, etc. argument to make sure they "look like" data. Are they of the proper dimension, or variable type, etc.
There are lots of functions in matlab of the form
is*()
that will check various data attributes.

Sign in to comment.

dpb
dpb on 28 Jun 2014
...wrongArray is not the data structure that the 'target' operations is intended to operate on, either because it contains the wrong sort of data, or is the wrong size.
...how is the code supposed to know that wrongArray is not the data structure that the "target" operations is intended to operate on, given that there really isn't any difference between this example and the previous one?...
Well, the latter is easy presuming that in the "target" operation there's an implied required size. The other is somewhat more problematical, but probably the easiest way to solve it would be to have an ID field in the structure that you can query to ascertain the type. Somewhat akin to the 'Type' property of the handle graphics objects.
get(gca,'type')
always returns the string 'axes'. Of course one never needs to query gca, but given a random handle that's just a floating point value, it's a useful thing to ask. Such a scheme could be implemented here to build a more-or-less polymorphic interface it seems.
Alternatively, there's the o-oriented approach again where each data object has its own methods so can't mistakenly operate on the wrong kind. I've "done nothink" to paraphrase Sgt Schultz w/o classes and all in Matlab so I've no input on the specifics of building such, but it would seem theoretically doable that would from what little I do understand. I'm an old fogey and this dog hasn't attempted any of that new-fangled stuff and isn't likely too...

Categories

Asked:

Ben
on 28 Jun 2014

Answered:

dpb
on 28 Jun 2014

Community Treasure Hunt

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

Start Hunting!