function subsrefcheck(Obj, S)
nRequiredArguments = 2;
nOptionalArguments = 0;
error(nargchk(nRequiredArguments, nRequiredArguments+nOptionalArguments, nargin, 'struct'));
validatesubstruct(S);
if length(S) >= 1 && strcmp(S(1).type, '.')
SubsNameString = S(1).subs;
SubObj = Obj;
elseif length(S) >= 2 && strcmp(S(1).type, '()') && strcmp(S(2).type, '.')
SubsNameString = S(2).subs;
SubObj = Obj(S(1).subs{:});
else
return;
end
switch lower(gettype(Obj, SubsNameString))
case 'field'
case 'property'
[GetAccessString, SetAccessString] = getpropertyaccess(SubObj, SubsNameString);
if ~strcmp(GetAccessString, 'public')
throwAsCaller(MException('MATLAB:class:GetProhibited', ...
['Getting the ''', SubsNameString, ''' property of the ''', class(Obj), ''' class is not allowed.']));
end
case 'method'
AccessString = getmethodaccess(SubObj, SubsNameString);
if ~strcmp(AccessString, 'public')
throwAsCaller(MException( ...
'MATLAB:class:MethodRestricted', ...
['Cannot access method ''', SubsNameString, ''' in class ''', class(Obj), ''.']));
end
otherwise
throwAsCaller(MException('MATLAB:noSuchMethodOrField', ...
[ 'No appropriate method, property, or field ', SubsNameString, ' for class ', class(Obj), '.']));
end
end
function validatesubstruct(S)
nRequiredArguments = 1;
nOptionalArguments = 0;
error(nargchk(nRequiredArguments, nRequiredArguments+nOptionalArguments, nargin, 'struct'));
assert(isstruct(S), 'MATLAB:subsArgNotStruc', ...
'Subscript argument to SUBSREF and SUBSASGN must be a structure.');
assert(length(fieldnames(S)) == 2, 'MATLAB:subsMustHaveTwo', ...
'Subscript argument to SUBSREF and SUBSASGN must have two fields.');
assert(isequal(sort(fieldnames(S)), sort({'subs'; 'type'})), ...
'MATLAB:subsMustHaveTypeSubs', ['Subscript argument to SUBSREF ', ...
'and SUBSASGN must have two fields whose names are "type" ', ...
'and "subs".']);
assert(~isempty(S), 'MATLAB:subsArgEmpty', ...
'Subscript argument to SUBSREF and SUBSASGN must not be empty.');
assert(all(cellfun(@(x)(ischar(x) || iscell(x)), {S.subs})), ...
'MATLAB:subsSubsMustBeCellOrChar', ...
['The "subs" field for the subscript argument to SUBSREF ', ...
'and SUBSASGN must be a cell or character array.']);
assert(all(cellfun(@(x)ischar(x), {S.type})), ...
'MATLAB:subsTypeMustBeChar', ...
['The "type" field for the subscript argument to SUBSREF ', ...
'and SUBSASGN ', '\n', 'must be a character array.']);
assert(all(cellfun(@(x)any(strcmp(x, {'.'; '()'; '{}'})), {S.type})), ...
'MATLAB:subsTypeMustBeSquigglyOrSmooth', ...
['The "type" field for the subscript argument to SUBSREF ', ...
'and SUBSASGN ', '\n', 'must be a character array ', ...
'of "." or "{}" or "()".']);
assert(all(cellfun(@(x, y)(~strcmp(x, '.') || ~iscell(y) ...
|| ~isempty(y)), {S.type}, {S.subs})), ...
'MATLAB:subsCellIsEmpty', ...
['The "subs" field for the subscript argument to SUBSREF ', ...
'and SUBSASGN must be a non-empty cell or character array.']);
for iSub = 1:length(S)
assert(~strcmp(S(iSub).type, '()') || iscell(S(iSub).subs), ...
'MATLAB:subsSmoothTypeSubsMustBeCell', ...
'SUBS field must be a cell array for () TYPE.');
assert(~strcmp(S(iSub).type, '{}') || iscell(S(iSub).subs), ...
'MATLAB:subsSquigglyTypeSubsMustBeCell', ...
'SUBS field must be a cell array for {} TYPE.');
assert(~strcmp(S(iSub).type, '()') || (iSub == length(S) || ...
strcmp(S(iSub+1).type, '.')) , ...
'MATLAB:subsDotMustFollow', ...
'Only a dot field name can follow ()''s.');
end
end
function AccessString = getmethodaccess(Obj, MethodNameString)
nRequiredArguments = 2;
nOptionalArguments = 0;
error(nargchk(nRequiredArguments, nRequiredArguments+nOptionalArguments, nargin, 'struct'));
assert(isobject(Obj), [mfilename, ':ArgumentCheck'], ...
['The Obj of class ''', class(Obj), ''' is not an object of a MATLAB class.']);
validateattributes(MethodNameString, {'char'}, {'row'}, [mfilename, ':ArgumentCheck'], 'MethodNameString');
MetaClassObj = metaclass(Obj);
NameList = {MetaClassObj.MethodList(:).Name};
iMethod = find(strcmp(MethodNameString, NameList), 1, 'first');
assert(~isempty(iMethod), [mfilename, ':ArgumentCheck'], ...
['''', MethodNameString, ''' is not a method of the ''', class(Obj), ''' class.']);
AccessString = MetaClassObj.MethodList(iMethod).Access;
end
function [GetAccessString, SetAccessString] = getpropertyaccess(Obj, PropertyNameString)
nRequiredArguments = 2;
nOptionalArguments = 0;
error(nargchk(nRequiredArguments, nRequiredArguments+nOptionalArguments, nargin, 'struct'));
assert(isobject(Obj), [mfilename, ':ArgumentCheck'], ...
['The Obj of class ''', class(Obj), ''' is not an object of a MATLAB class.']);
validateattributes(PropertyNameString, {'char'}, {'row'}, [mfilename, ':ArgumentCheck'], 'PropertyNameString');
MetaClassObj = metaclass(Obj);
NameList = {MetaClassObj.PropertyList(:).Name};
iProperty = find(strcmp(PropertyNameString, NameList), 1, 'first');
assert(~isempty(iProperty), [mfilename, ':ArgumentCheck'], ...
['''', PropertyNameString, ''' is not a property of the ''', class(Obj), ''' class.']);
GetAccessString = MetaClassObj.PropertyList(iProperty).GetAccess;
SetAccessString = MetaClassObj.PropertyList(iProperty).SetAccess;
end
Best Answer