Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
class input validation

Subject: class input validation

From: Mike

Date: 14 Jan, 2010 18:09:24

Message: 1 of 4

I have a class that has a large number of variables, and most of them need to be restricted to certain values. For instance:

classdef TempClass
   properties
      propA % numeric
      propB % only 'yes' or 'no'
      propC % only 'html', 'xml', 'pdf', or 'txt'
      propD % only 'yes' or 'no'
      propE % only 'yes' or 'no'
      propF % only 'yes' or 'no'
   end % properties
end

In this example, propB, propD, propE, and propF all need to be restricted to the same set of values. Is there a slick way to bullet-proof these all? Obviously, I could write a set method for each one, like this:

function me = set.propB(me,val)
   p = inputParser;
   p.addRequired('propB',@(x)ischar(x)&&any(strcmpi(x,{'yes','no'}))));
      % The ischar(x) removes cell inputs from contention
   p.parse(val);
   me.(p.Parameters{1}) = p.Results.(p.Parameters{1});
end

Is there a way to write a generic set function, something like:
function me = set.genericYesNo(me,paramName,val)
   % Should probably bullet-proof the paramName input
   p = inputParser;
   p.addRequired(paramName,@(x)ischar(x)&&any(strcmpi(x,{'yes','no'}))));
      % The ischar(x) removes cell inputs from contention
   p.parse(val);
   me.(p.Parameters{1}) = p.Results.(p.Parameters{1});
end

I don't see how that particular syntax would ever get called, but it would sure speed up code writing and improve code maintenance.

It would also be handy to have a 4th argument, 'validation' that, in that example would contain "@(x)ischar(x)&&any(strcmpi(x,{'yes','no'})))." That way, one set function could work for all possible parameters. Or, maybe instead of as an input, each class parameter needs a validator, just like the inputParser requires a validator for each input. That way, when set.propB gets called, it automatically checks to see if the input passes the propB validator.

Any suggestions on how to implement this?

Subject: class input validation

From: Matt J

Date: 14 Jan, 2010 18:43:05

Message: 2 of 4

"Mike " <mdp.public.we.dont.need.no.stinking.spam@gmail.com> wrote in message <hinmkk$rht$1@fred.mathworks.com>...



Well, one thing you could do is, instead of having all these variables as separate properties, you could make a single struct property, call it propStruct with all these variables as fieldnames. You would then only have to write a set method for propStruct and can use struct manipulation functions to parse the fields and the allowing values getting assigned to them.

This would mean of course that, inside the classdef you would have to refer to these properties via obj.propStruct.propA and so forth. That might seem cumbersome, but this FEX tool could help with that

http://www.mathworks.com/matlabcentral/fileexchange/26216-structure-fields-to-variables

Outside the classdef file you could still access these properties using the syntax obj.propA if you overload subsref appropriately.

Subject: class input validation

From: Mike

Date: 14 Jan, 2010 21:55:06

Message: 3 of 4

Thanks for posting that. It's an interesting method. Is there a slick way to evaluate more than one of the assignments at a time? I get all sorts of variations on "eval can't handle cells" and "you can't add variables to static workspaces" when I try things like:

>>assigns = cellfun(@(f)[f ' = localStructname.' f ';'],fields,'uniformoutput',0);
>>eval(assigns)
or
>>eval(assigns{:})
or
>>cellfun(@(f)eval(f),assigns(:))

Running
>>eval(assigns{end})
yields what I would expect.

Thanks in advance.

Subject: class input validation

From: Matt J

Date: 14 Jan, 2010 22:15:20

Message: 4 of 4

"Mike " <Michael.D.Pulsipher.we.don't.need.no.stinking.spam@L-3com.com> wrote in message <hio3rq$67j$1@fred.mathworks.com>...
> Thanks for posting that. It's an interesting method. Is there a slick way to evaluate more than one of the assignments at a time? I get all sorts of variations on "eval can't handle cells" and "you can't add variables to static workspaces" when I try things like:
>
> >>assigns = cellfun(@(f)[f ' = localStructname.' f ';'],fields,'uniformoutput',0);
> >>eval(assigns)
> or
> >>eval(assigns{:})
> or
> >>cellfun(@(f)eval(f),assigns(:))
>
> Running
> >>eval(assigns{end})
> yields what I would expect.

It's a busy day on this topic. This is the 3rd or 4th thread to discuss it...

In general, it's hazardous to introduce a variable into a workspace without an explicit assignment command, e.g. using load/eval/assignin etc..., and some environments (like the static workspaces you mentioned) simply won't let you.

This is a practice called "poofing" in some circles. It was to provide a non-hazardous alternative to poofing that I created the structvars() tool.

In answer to your question, you can use the structvars() tool in conjunction with
eval() to execute the assignments that it prints:

eval(structvars(S).');

but it's simply another variation on poofing like the examples you've listed and with all the same dangers.

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us