Mercurial > hg > ltpda
diff m-toolbox/classes/+utils/@helper/callerIsMethod.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m-toolbox/classes/+utils/@helper/callerIsMethod.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,157 @@ +% CALLERISMETHOD(varargin) checks if a method was called by another LTPDA method. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% DESCRIPTION: CALLERISMETHOD(varargin) checks if the method it is inserted in, +% was called by another LTPDA method +% +% CALL: callerIsMethod = utils.helper.callerIsMethod() +% [callerIsMethod, className] = utils.helper.callerIsMethod() +% [callerIsMethod, className, methodName] = utils.helper.callerIsMethod() +% +% The name of the caller function is retrieved from a call to dbstack +% +% The name of the higher level caller function, if any is tested against the structure +% /../../classes/@class_name/method_name.m +% +% If the higher level caller is found to be a method of LTPDA classes, out is TRUE +% If the caller is found not to be a method of LTPDA classes, out is FALSE +% +% Optional outputs: +% className the name of the class the caller methods is associated +% methodName the name of the caller method is associated +% +% HISTORY: 09-02-11 M Hueller +% Creation +% +% VERSION: $Id: callerIsMethod.m,v 1.16 2011/04/09 06:58:47 hewitson Exp $ +% +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function varargout = callerIsMethod(varargin) + + % This is just some thinking about make a scheme that can override the + % behaviour of callerIsMethod. The idea is to create a variable called + % 'callerIsMethod' in the calling function and pass it in here. We would + % have to pass varargin and inputnames down the chain always. It almost + % works but will be too much work for the moment. + % if nargin == 2 + % + % inputs = varargin{1}; + % names = varargin{2}; + % + % idx = strcmpi('callerIsMethod', names); + % if any(idx) + % varargout{1} = inputs{idx}; + % return + % end + % end + + persistent exceptions; + + if isempty(exceptions) + exceptions = {'compute', 'rebuild', 'collect_values', 'generic_getInfo', 'executeCommands'}; + end + + stack = dbstack('-completenames'); + index = 2; + + if size (stack, 1) < index + error('### This utility can only be used inside other functions!'); + end + + if size (stack, 1) == index + + % This is the highest level function call. + % The caller is not a method + callerIsMethod = false; + className = []; + methodName = []; + + else + % This is not the highest level function call. + + % Serching for class methods assuming the folder/files structure is: + % /../../classes/@class_name/method_name.m + + % In the case that we are inside a nested function, we need to climb up + % until we get out of the calling file. + firstFile = stack(index).file; + firstName = stack(index).name; + + while index < length(stack) && strcmp(firstFile, stack(index).file) && ~strcmp(firstName, stack(index+1).name) + index = index+1; + end + + % capture method name + methodName = stack(index).name; + + if index == length(stack) && length(stack)>3 + callerIsMethod = false; + className = ''; + else + % filesep is quite slow, so we cache the value and use it three times. + % The \ character is also a command in regexp, so we need to go for a trick + if strncmp(computer, 'PC', 2) + fs = '\\'; + else + fs = '/'; + end + + % capture class name + tokenStr = regexp(stack(index).file, ['.*' fs '@(\w+)' fs '\w+.m$'], 'tokens'); + + % ********* + % At the moment this bit of code is a bad thing because models which + % create objects in their default plists (AOs for example) can't be + % rebuilt because the objects have no history. An example of this is + % smodel_model_psd_feeps. + % ********* + +% % If we are being called deep inside a built-in model constructor, +% % then the stack will contain fromModel and we are called from a +% % method. +% if utils.helper.ismember('fromModel', {stack(:).name}) +% callerIsMethod = true; +% className = 'ltpda_uo'; +% methodName = 'fromModel'; +% +% % If the method is a unit test (test_*) then we add history +% else + + + if strncmp(methodName, 'test_', 5) + callerIsMethod = false; + if ~isempty(tokenStr) + className = tokenStr{1}{1}; + end + + % if we get a match and if the caller is not in the exception list + % then we were called by a method. + elseif ~isempty(tokenStr) && ~any(strcmp(stack(index).name, exceptions)) + callerIsMethod = true; + className = tokenStr{1}{1}; + else + callerIsMethod = false; + className = ''; + end + end + + end + + % Assigning outputs + switch nargout + case 0 + case 1 + varargout{1} = callerIsMethod; + case 2 + varargout{1} = callerIsMethod; + varargout{2} = className; + case 3 + varargout{1} = callerIsMethod; + varargout{2} = className; + varargout{3} = methodName; + otherwise + error('### Incorrect number of outputs'); + end +end