Changes between Version 2 and Version 3 of DynamicCallAnalysis
- Timestamp:
- Sep 27, 2012, 6:20:36 PM (12 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
DynamicCallAnalysis
v2 v3 46 46 }}} 47 47 48 49 == User-defined function references 50 51 The dynamic function analyser is equipped to handle user-defined function references. This functionality is basically a generalisation of the analysis of {{{erlang:apply/3}}} calls, where the actual arguments of a function call determine another function which is, we say, symbolically referred to inside the original call. In this kind of extended reference analysis, the user can specify that: which functions, and in which of their arguments do refer to other functions. 52 53 In Erlang it is sometimes preferable to define functions that act as a wrapper to a simple ''apply''. Typical use cases include load distribution among different Erlang nodes as well as practical implementations of callback functions. With user-defined function references, the wrapper function will actually refer to the function(s) that may be called inside its body. 54 48 55 {{{#!comment 49 50 == Configurable dynamic function analyzer ==51 52 Dynamic function analyzer was extended to handle user defined functions that has semantics similar to apply BIF.53 54 In Erlang it is sometimes preferable to use custom functions that act as a wrapper for a simple apply.55 For example for load distribution among different Erlang nodes. Or implementing callback functions.56 57 56 === Small example === 58 57 … … 111 110 }}} 112 111 113 A user-defined references to link from the original function call was made. 114 115 === How to specify a valid Erlang match specification === 112 A user-defined references to link from the original function call was made. 113 }}} 114 115 === How to specify user-defined references 116 117 The specification has to be put in a configuration file in the root directory of your instance of the tool (the file has to be named {{{dynfunref.conf}}}). It should contain tuples of the following form. 118 116 119 {{{#!erlang 117 120 { 118 {erlang, apply}, %analyzed module and function 119 ['$1', '$2', '$3'], %match 120 [{'$1', '$2', '$3'}] %where to link (an exact function) 121 {foo, bar}, 122 ['$1', '$2', '$3'], 123 [ 124 {'$1', '$2', '$3'}, 125 {'$2', {'$1', foo, 0}} 126 ] 121 127 }. 122 128 }}} 123 The first element of the tuple is a tuple, which first element is the name of the module in which the analyzed function is located. The name of the function is at the second element. 124 The second element is a list of match specs. Its length equals to the arity of the analyzed function. 125 The third argument is a list of mappings represented by tuples. One element of a mapping is a 3-tuple representing an exact function. The third element is represent arity rather than agrments. 126 127 === Another example === 128 Consider the following 2 module. 129 130 The first two elements determine the function whose arguments are to be inspected: the module name and the function name are given in the first element of the tuple, while the function arity is determined by the length of the second element. The list in the second element is a pattern (a simple version of Erlang match specifications) which allows its elements to be any Erlang term constructed of lists, tuples and atoms (atoms will be regarded as variable names, and they match with any term). 131 132 When analysing an appropriate function call, its actual parameters are matched with the pattern, and then the atoms become bound variable names within the third element of the specification tuple. The third element defines mappings: which arguments refer to which functions - if the mapping is a pair, the first element defines the source of the reference and the second determines the callee, if it is a 3-tuple, then a function reference will point from the original call expression to the specified function. 133 134 The first and second elements of callee specifications may be arbitrary atoms as they determine the module and function name of the callee: if the atom has been bound in the argument pattern, then the value of the actual argument will be used. The third element of the callee specification may be an integer or an atom and it determines the arity of the callee: if it is an atom, then the corresponding element in the argument match will be treated as a list and will be counted, otherwise the integer constant will be the arity of the callee. 135 136 137 === Example 138 139 Consider the following 2 modules. 140 129 141 {{{#!erlang 130 142 -module(router). … … 184 196 185 197 The result: 186 {{{ #!erlang198 {{{ 187 199 (refactorerl@localhost)26> ri:reset(). 188 200 {ok,[]} … … 215 227 }}} 216 228 217 A dynamic function referencewere made to link {{{router_backend:a/1}}} to {{{router:ex_call/0 }}},229 Dynamic references were made to link {{{router_backend:a/1}}} to {{{router:ex_call/0 }}}, 218 230 and to link {{{router_backend:b/2}}} to {{{router:ex_call2/0}}}. 219 }}}