comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:f0afece42f48
1 % CALLERISMETHOD(varargin) checks if a method was called by another LTPDA method.
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %
4 % DESCRIPTION: CALLERISMETHOD(varargin) checks if the method it is inserted in,
5 % was called by another LTPDA method
6 %
7 % CALL: callerIsMethod = utils.helper.callerIsMethod()
8 % [callerIsMethod, className] = utils.helper.callerIsMethod()
9 % [callerIsMethod, className, methodName] = utils.helper.callerIsMethod()
10 %
11 % The name of the caller function is retrieved from a call to dbstack
12 %
13 % The name of the higher level caller function, if any is tested against the structure
14 % /../../classes/@class_name/method_name.m
15 %
16 % If the higher level caller is found to be a method of LTPDA classes, out is TRUE
17 % If the caller is found not to be a method of LTPDA classes, out is FALSE
18 %
19 % Optional outputs:
20 % className the name of the class the caller methods is associated
21 % methodName the name of the caller method is associated
22 %
23 % HISTORY: 09-02-11 M Hueller
24 % Creation
25 %
26 % VERSION: $Id: callerIsMethod.m,v 1.16 2011/04/09 06:58:47 hewitson Exp $
27 %
28 %
29 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
30
31 function varargout = callerIsMethod(varargin)
32
33 % This is just some thinking about make a scheme that can override the
34 % behaviour of callerIsMethod. The idea is to create a variable called
35 % 'callerIsMethod' in the calling function and pass it in here. We would
36 % have to pass varargin and inputnames down the chain always. It almost
37 % works but will be too much work for the moment.
38 % if nargin == 2
39 %
40 % inputs = varargin{1};
41 % names = varargin{2};
42 %
43 % idx = strcmpi('callerIsMethod', names);
44 % if any(idx)
45 % varargout{1} = inputs{idx};
46 % return
47 % end
48 % end
49
50 persistent exceptions;
51
52 if isempty(exceptions)
53 exceptions = {'compute', 'rebuild', 'collect_values', 'generic_getInfo', 'executeCommands'};
54 end
55
56 stack = dbstack('-completenames');
57 index = 2;
58
59 if size (stack, 1) < index
60 error('### This utility can only be used inside other functions!');
61 end
62
63 if size (stack, 1) == index
64
65 % This is the highest level function call.
66 % The caller is not a method
67 callerIsMethod = false;
68 className = [];
69 methodName = [];
70
71 else
72 % This is not the highest level function call.
73
74 % Serching for class methods assuming the folder/files structure is:
75 % /../../classes/@class_name/method_name.m
76
77 % In the case that we are inside a nested function, we need to climb up
78 % until we get out of the calling file.
79 firstFile = stack(index).file;
80 firstName = stack(index).name;
81
82 while index < length(stack) && strcmp(firstFile, stack(index).file) && ~strcmp(firstName, stack(index+1).name)
83 index = index+1;
84 end
85
86 % capture method name
87 methodName = stack(index).name;
88
89 if index == length(stack) && length(stack)>3
90 callerIsMethod = false;
91 className = '';
92 else
93 % filesep is quite slow, so we cache the value and use it three times.
94 % The \ character is also a command in regexp, so we need to go for a trick
95 if strncmp(computer, 'PC', 2)
96 fs = '\\';
97 else
98 fs = '/';
99 end
100
101 % capture class name
102 tokenStr = regexp(stack(index).file, ['.*' fs '@(\w+)' fs '\w+.m$'], 'tokens');
103
104 % *********
105 % At the moment this bit of code is a bad thing because models which
106 % create objects in their default plists (AOs for example) can't be
107 % rebuilt because the objects have no history. An example of this is
108 % smodel_model_psd_feeps.
109 % *********
110
111 % % If we are being called deep inside a built-in model constructor,
112 % % then the stack will contain fromModel and we are called from a
113 % % method.
114 % if utils.helper.ismember('fromModel', {stack(:).name})
115 % callerIsMethod = true;
116 % className = 'ltpda_uo';
117 % methodName = 'fromModel';
118 %
119 % % If the method is a unit test (test_*) then we add history
120 % else
121
122
123 if strncmp(methodName, 'test_', 5)
124 callerIsMethod = false;
125 if ~isempty(tokenStr)
126 className = tokenStr{1}{1};
127 end
128
129 % if we get a match and if the caller is not in the exception list
130 % then we were called by a method.
131 elseif ~isempty(tokenStr) && ~any(strcmp(stack(index).name, exceptions))
132 callerIsMethod = true;
133 className = tokenStr{1}{1};
134 else
135 callerIsMethod = false;
136 className = '';
137 end
138 end
139
140 end
141
142 % Assigning outputs
143 switch nargout
144 case 0
145 case 1
146 varargout{1} = callerIsMethod;
147 case 2
148 varargout{1} = callerIsMethod;
149 varargout{2} = className;
150 case 3
151 varargout{1} = callerIsMethod;
152 varargout{2} = className;
153 varargout{3} = methodName;
154 otherwise
155 error('### Incorrect number of outputs');
156 end
157 end