Update version according to OSCI-856
[packages/precise/mcollective.git] / doc / classes / MCollective / Matcher.html
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html 
3      PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8   <title>Module: MCollective::Matcher</title>
9   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10   <meta http-equiv="Content-Script-Type" content="text/javascript" />
11   <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12   <script type="text/javascript">
13   // <![CDATA[
14
15   function popupCode( url ) {
16     window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17   }
18
19   function toggleCode( id ) {
20     if ( document.getElementById )
21       elem = document.getElementById( id );
22     else if ( document.all )
23       elem = eval( "document.all." + id );
24     else
25       return false;
26
27     elemStyle = elem.style;
28     
29     if ( elemStyle.display != "block" ) {
30       elemStyle.display = "block"
31     } else {
32       elemStyle.display = "none"
33     }
34
35     return true;
36   }
37   
38   // Make codeblocks hidden by default
39   document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40   
41   // ]]>
42   </script>
43
44 </head>
45 <body>
46
47
48
49     <div id="classHeader">
50         <table class="header-table">
51         <tr class="top-aligned-row">
52           <td><strong>Module</strong></td>
53           <td class="class-name-in-header">MCollective::Matcher</td>
54         </tr>
55         <tr class="top-aligned-row">
56             <td><strong>In:</strong></td>
57             <td>
58                 <a href="../../files/lib/mcollective/matcher/scanner_rb.html">
59                 lib/mcollective/matcher/scanner.rb
60                 </a>
61         <br />
62                 <a href="../../files/lib/mcollective/matcher/parser_rb.html">
63                 lib/mcollective/matcher/parser.rb
64                 </a>
65         <br />
66                 <a href="../../files/lib/mcollective/matcher_rb.html">
67                 lib/mcollective/matcher.rb
68                 </a>
69         <br />
70             </td>
71         </tr>
72
73         </table>
74     </div>
75   <!-- banner header -->
76
77   <div id="bodyContent">
78
79
80
81   <div id="contextContent">
82
83     <div id="description">
84       <p>
85 A parser and scanner that creates a stack machine for a simple fact and
86 class matching language used on the CLI to facilitate a rich discovery
87 language
88 </p>
89 <p>
90 Language EBNF
91 </p>
92 <p>
93 compound = [&quot;(&quot;] expression [&quot;)&quot;] {[&quot;(&quot;]
94 expression [&quot;)&quot;]} expression = [!|not]statement
95 [&quot;and&quot;|&quot;or&quot;] [!|not] statement char = A-Z | a-z | &lt;
96 | &gt; | =&gt; | =&lt; | _ | - |* | / { A-Z | a-z | &lt; | &gt; | =&gt; |
97 =&lt; | _ | - | * | / | } int = 0|1|2|3|4|5|6|7|8|9{|0|1|2|3|4|5|6|7|8|9|0}
98 </p>
99
100     </div>
101
102
103    </div>
104
105     <div id="method-list">
106       <h3 class="section-bar">Methods</h3>
107
108       <div class="name-list">
109       <a href="#M000147">create_compound_callstack</a>&nbsp;&nbsp;
110       <a href="#M000143">create_function_hash</a>&nbsp;&nbsp;
111       <a href="#M000146">eval_compound_fstatement</a>&nbsp;&nbsp;
112       <a href="#M000145">eval_compound_statement</a>&nbsp;&nbsp;
113       <a href="#M000144">execute_function</a>&nbsp;&nbsp;
114       </div>
115     </div>
116
117   </div>
118
119
120     <!-- if includes -->
121
122     <div id="section">
123
124     <div id="class-list">
125       <h3 class="section-bar">Classes and Modules</h3>
126
127       Class <a href="Matcher/Parser.html" class="link">MCollective::Matcher::Parser</a><br />
128 Class <a href="Matcher/Scanner.html" class="link">MCollective::Matcher::Scanner</a><br />
129
130     </div>
131
132
133
134
135       
136
137
138     <!-- if method_list -->
139     <div id="methods">
140       <h3 class="section-bar">Public Class methods</h3>
141
142       <div id="method-M000147" class="method-detail">
143         <a name="M000147"></a>
144
145         <div class="method-heading">
146           <a href="#M000147" class="method-signature">
147           <span class="method-name">create_compound_callstack</span><span class="method-args">(call_string)</span>
148           </a>
149         </div>
150       
151         <div class="method-description">
152           <p>
153 Creates a callstack to be evaluated from a compound evaluation string
154 </p>
155           <p><a class="source-toggle" href="#"
156             onclick="toggleCode('M000147-source');return false;">[Source]</a></p>
157           <div class="method-source-code" id="M000147-source">
158 <pre>
159      <span class="ruby-comment cmt"># File lib/mcollective/matcher.rb, line 181</span>
160 181:     <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">create_compound_callstack</span>(<span class="ruby-identifier">call_string</span>)
161 182:       <span class="ruby-identifier">callstack</span> = <span class="ruby-constant">Matcher</span><span class="ruby-operator">::</span><span class="ruby-constant">Parser</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">call_string</span>).<span class="ruby-identifier">execution_stack</span>
162 183:       <span class="ruby-identifier">callstack</span>.<span class="ruby-identifier">each_with_index</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">statement</span>, <span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
163 184:         <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">statement</span>.<span class="ruby-identifier">keys</span>.<span class="ruby-identifier">first</span> <span class="ruby-operator">==</span> <span class="ruby-value str">&quot;fstatement&quot;</span>
164 185:           <span class="ruby-identifier">callstack</span>[<span class="ruby-identifier">i</span>][<span class="ruby-value str">&quot;fstatement&quot;</span>] = <span class="ruby-identifier">create_function_hash</span>(<span class="ruby-identifier">statement</span>.<span class="ruby-identifier">values</span>.<span class="ruby-identifier">first</span>)
165 186:         <span class="ruby-keyword kw">end</span>
166 187:       <span class="ruby-keyword kw">end</span>
167 188:       <span class="ruby-identifier">callstack</span>
168 189:     <span class="ruby-keyword kw">end</span>
169 </pre>
170           </div>
171         </div>
172       </div>
173
174       <div id="method-M000143" class="method-detail">
175         <a name="M000143"></a>
176
177         <div class="method-heading">
178           <a href="#M000143" class="method-signature">
179           <span class="method-name">create_function_hash</span><span class="method-args">(function_call)</span>
180           </a>
181         </div>
182       
183         <div class="method-description">
184           <p>
185 Helper creates a hash from a function call string
186 </p>
187           <p><a class="source-toggle" href="#"
188             onclick="toggleCode('M000143-source');return false;">[Source]</a></p>
189           <div class="method-source-code" id="M000143-source">
190 <pre>
191     <span class="ruby-comment cmt"># File lib/mcollective/matcher.rb, line 17</span>
192 17:     <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">create_function_hash</span>(<span class="ruby-identifier">function_call</span>)
193 18:       <span class="ruby-identifier">func_hash</span> = {}
194 19:       <span class="ruby-identifier">f</span> = <span class="ruby-value str">&quot;&quot;</span>
195 20:       <span class="ruby-identifier">func_parts</span> = <span class="ruby-identifier">function_call</span>.<span class="ruby-identifier">split</span>(<span class="ruby-regexp re">/(!=|&gt;=|&lt;=|&lt;|&gt;|=)/</span>)
196 21:       <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;r_compare&quot;</span>] = <span class="ruby-identifier">func_parts</span>.<span class="ruby-identifier">pop</span>
197 22:       <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;operator&quot;</span>] = <span class="ruby-identifier">func_parts</span>.<span class="ruby-identifier">pop</span>
198 23:       <span class="ruby-identifier">func</span> = <span class="ruby-identifier">func_parts</span>.<span class="ruby-identifier">join</span>
199 24: 
200 25:       <span class="ruby-comment cmt"># Deal with dots in function parameters and functions without dot values</span>
201 26:       <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">func</span>.<span class="ruby-identifier">match</span>(<span class="ruby-regexp re">/^.+\(.*\)$/</span>)
202 27:         <span class="ruby-identifier">f</span> = <span class="ruby-identifier">func</span>
203 28:       <span class="ruby-keyword kw">else</span>
204 29:         <span class="ruby-identifier">func_parts</span> = <span class="ruby-identifier">func</span>.<span class="ruby-identifier">split</span>(<span class="ruby-value str">&quot;.&quot;</span>)
205 30:         <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;value&quot;</span>] = <span class="ruby-identifier">func_parts</span>.<span class="ruby-identifier">pop</span>
206 31:         <span class="ruby-identifier">f</span> = <span class="ruby-identifier">func_parts</span>.<span class="ruby-identifier">join</span>(<span class="ruby-value str">&quot;.&quot;</span>)
207 32:       <span class="ruby-keyword kw">end</span>
208 33: 
209 34:       <span class="ruby-comment cmt"># Deal with regular expression matches</span>
210 35:       <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;r_compare&quot;</span>] <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/^\/.*\/$/</span>
211 36:         <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;operator&quot;</span>] = <span class="ruby-value str">&quot;=~&quot;</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;operator&quot;</span>] <span class="ruby-operator">==</span> <span class="ruby-value str">&quot;=&quot;</span>
212 37:         <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;operator&quot;</span>] = <span class="ruby-value str">&quot;!=~&quot;</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;operator&quot;</span>] <span class="ruby-operator">==</span> <span class="ruby-value str">&quot;!=&quot;</span>
213 38:         <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;r_compare&quot;</span>] = <span class="ruby-constant">Regexp</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;r_compare&quot;</span>].<span class="ruby-identifier">gsub</span>(<span class="ruby-regexp re">/^\/|\/$/</span>, <span class="ruby-value str">&quot;&quot;</span>))
214 39:       <span class="ruby-comment cmt"># Convert = operators to == so they can be propperly evaluated</span>
215 40:       <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;operator&quot;</span>] <span class="ruby-operator">==</span> <span class="ruby-value str">&quot;=&quot;</span>
216 41:         <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;operator&quot;</span>] = <span class="ruby-value str">&quot;==&quot;</span>
217 42:       <span class="ruby-keyword kw">end</span>
218 43: 
219 44:       <span class="ruby-comment cmt"># Grab function name and parameters from left compare string</span>
220 45:       <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;name&quot;</span>], <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;params&quot;</span>] = <span class="ruby-identifier">f</span>.<span class="ruby-identifier">split</span>(<span class="ruby-value str">&quot;(&quot;</span>)
221 46:       <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;params&quot;</span>] <span class="ruby-operator">==</span> <span class="ruby-value str">&quot;)&quot;</span>
222 47:         <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;params&quot;</span>] = <span class="ruby-keyword kw">nil</span>
223 48:       <span class="ruby-keyword kw">else</span>
224 49: 
225 50:         <span class="ruby-comment cmt"># Walk the function parameters from the front and from the</span>
226 51:         <span class="ruby-comment cmt"># back removing the first and last instances of single of</span>
227 52:         <span class="ruby-comment cmt"># double qoutes. We do this to handle the case where params</span>
228 53:         <span class="ruby-comment cmt"># contain escaped qoutes.</span>
229 54:         <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;params&quot;</span>] = <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;params&quot;</span>].<span class="ruby-identifier">gsub</span>(<span class="ruby-value str">&quot;)&quot;</span>, <span class="ruby-value str">&quot;&quot;</span>)
230 55:         <span class="ruby-identifier">func_quotes</span> = <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;params&quot;</span>].<span class="ruby-identifier">split</span>(<span class="ruby-regexp re">/('|&quot;)/</span>)
231 56: 
232 57:         <span class="ruby-identifier">func_quotes</span>.<span class="ruby-identifier">each_with_index</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">item</span>, <span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
233 58:           <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">item</span>.<span class="ruby-identifier">match</span>(<span class="ruby-regexp re">/'|&quot;/</span>)
234 59:             <span class="ruby-identifier">func_quotes</span>.<span class="ruby-identifier">delete_at</span>(<span class="ruby-identifier">i</span>)
235 60:             <span class="ruby-keyword kw">break</span>
236 61:           <span class="ruby-keyword kw">end</span>
237 62:         <span class="ruby-keyword kw">end</span>
238 63: 
239 64:         <span class="ruby-identifier">func_quotes</span>.<span class="ruby-identifier">reverse</span>.<span class="ruby-identifier">each_with_index</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">item</span>,<span class="ruby-identifier">i</span><span class="ruby-operator">|</span>
240 65:           <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">item</span>.<span class="ruby-identifier">match</span>(<span class="ruby-regexp re">/'|&quot;/</span>)
241 66:             <span class="ruby-identifier">func_quotes</span>.<span class="ruby-identifier">delete_at</span>(<span class="ruby-identifier">func_quotes</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">-</span> <span class="ruby-identifier">i</span> <span class="ruby-operator">-</span> <span class="ruby-value">1</span>)
242 67:             <span class="ruby-keyword kw">break</span>
243 68:           <span class="ruby-keyword kw">end</span>
244 69:         <span class="ruby-keyword kw">end</span>
245 70: 
246 71:         <span class="ruby-identifier">func_hash</span>[<span class="ruby-value str">&quot;params&quot;</span>] = <span class="ruby-identifier">func_quotes</span>.<span class="ruby-identifier">join</span>
247 72:       <span class="ruby-keyword kw">end</span>
248 73: 
249 74:       <span class="ruby-identifier">func_hash</span>
250 75:     <span class="ruby-keyword kw">end</span>
251 </pre>
252           </div>
253         </div>
254       </div>
255
256       <div id="method-M000146" class="method-detail">
257         <a name="M000146"></a>
258
259         <div class="method-heading">
260           <a href="#M000146" class="method-signature">
261           <span class="method-name">eval_compound_fstatement</span><span class="method-args">(function_hash)</span>
262           </a>
263         </div>
264       
265         <div class="method-description">
266           <p>
267 Returns the result of an evaluated compound statement that includes a
268 function
269 </p>
270           <p><a class="source-toggle" href="#"
271             onclick="toggleCode('M000146-source');return false;">[Source]</a></p>
272           <div class="method-source-code" id="M000146-source">
273 <pre>
274      <span class="ruby-comment cmt"># File lib/mcollective/matcher.rb, line 135</span>
275 135:     <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">eval_compound_fstatement</span>(<span class="ruby-identifier">function_hash</span>)
276 136:       <span class="ruby-identifier">l_compare</span> = <span class="ruby-identifier">execute_function</span>(<span class="ruby-identifier">function_hash</span>)
277 137: 
278 138:       <span class="ruby-comment cmt"># Break out early and return false if the function returns nil</span>
279 139:       <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">false</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">l_compare</span>
280 140: 
281 141:       <span class="ruby-comment cmt"># Prevent unwanted discovery by limiting comparison operators</span>
282 142:       <span class="ruby-comment cmt"># on Strings and Booleans</span>
283 143:       <span class="ruby-keyword kw">if</span>((<span class="ruby-identifier">l_compare</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">String</span>) <span class="ruby-operator">||</span> <span class="ruby-identifier">l_compare</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">TrueClass</span>) <span class="ruby-operator">||</span> <span class="ruby-identifier">l_compare</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">FalseClass</span>)) <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">function_hash</span>[<span class="ruby-value str">&quot;operator&quot;</span>].<span class="ruby-identifier">match</span>(<span class="ruby-regexp re">/&lt;|&gt;/</span>))
284 144:         <span class="ruby-constant">Log</span>.<span class="ruby-identifier">debug</span> <span class="ruby-node">&quot;Cannot do &gt; and &lt; comparison on Booleans and Strings '#{l_compare} #{function_hash[&quot;operator&quot;]} #{function_hash[&quot;r_compare&quot;]}'&quot;</span>
285 145:         <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">false</span>
286 146:       <span class="ruby-keyword kw">end</span>
287 147: 
288 148:       <span class="ruby-comment cmt"># Prevent backticks in function parameters</span>
289 149:       <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">function_hash</span>[<span class="ruby-value str">&quot;params&quot;</span>] <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/`/</span>
290 150:         <span class="ruby-constant">Log</span>.<span class="ruby-identifier">debug</span>(<span class="ruby-value str">&quot;Cannot use backticks in function parameters&quot;</span>)
291 151:         <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">false</span>
292 152:       <span class="ruby-keyword kw">end</span>
293 153: 
294 154:       <span class="ruby-comment cmt"># Escape strings for evaluation</span>
295 155:       <span class="ruby-identifier">function_hash</span>[<span class="ruby-value str">&quot;r_compare&quot;</span>] = <span class="ruby-node">&quot;\&quot;#{function_hash[&quot;r_compare&quot;]}\&quot;&quot;</span> <span class="ruby-keyword kw">if</span>(<span class="ruby-identifier">l_compare</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">String</span>)  <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-operator">!</span>(<span class="ruby-identifier">function_hash</span>[<span class="ruby-value str">&quot;operator&quot;</span>] <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/=~|!=~/</span>))
296 156: 
297 157:       <span class="ruby-comment cmt"># Do a regex comparison if right compare string is a regex</span>
298 158:       <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">function_hash</span>[<span class="ruby-value str">&quot;operator&quot;</span>] <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/(=~|!=~)/</span>
299 159:         <span class="ruby-comment cmt"># Fail if left compare value isn't a string</span>
300 160:         <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">l_compare</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">String</span>)
301 161:           <span class="ruby-constant">Log</span>.<span class="ruby-identifier">debug</span>(<span class="ruby-value str">&quot;Cannot do a regex check on a non string value.&quot;</span>)
302 162:           <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">false</span>
303 163:         <span class="ruby-keyword kw">else</span>
304 164:           <span class="ruby-identifier">compare_result</span> = <span class="ruby-identifier">l_compare</span>.<span class="ruby-identifier">match</span>(<span class="ruby-identifier">function_hash</span>[<span class="ruby-value str">&quot;r_compare&quot;</span>])
305 165:           <span class="ruby-comment cmt"># Flip return value for != operator</span>
306 166:           <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">function_hash</span>[<span class="ruby-value str">&quot;operator&quot;</span>] <span class="ruby-operator">==</span> <span class="ruby-value str">&quot;!=~&quot;</span>
307 167:             <span class="ruby-operator">!</span>((<span class="ruby-identifier">compare_result</span>.<span class="ruby-identifier">nil?</span>) <span class="ruby-operator">?</span> <span class="ruby-keyword kw">false</span> <span class="ruby-operator">:</span> <span class="ruby-keyword kw">true</span>)
308 168:           <span class="ruby-keyword kw">else</span>
309 169:             (<span class="ruby-identifier">compare_result</span>.<span class="ruby-identifier">nil?</span>) <span class="ruby-operator">?</span> <span class="ruby-keyword kw">false</span> <span class="ruby-operator">:</span> <span class="ruby-keyword kw">true</span>
310 170:           <span class="ruby-keyword kw">end</span>
311 171:         <span class="ruby-keyword kw">end</span>
312 172:         <span class="ruby-comment cmt"># Otherwise evaluate the logical comparison</span>
313 173:       <span class="ruby-keyword kw">else</span>
314 174:         <span class="ruby-identifier">l_compare</span> = <span class="ruby-node">&quot;\&quot;#{l_compare}\&quot;&quot;</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">l_compare</span>.<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">String</span>)
315 175:         <span class="ruby-identifier">result</span> = <span class="ruby-identifier">eval</span>(<span class="ruby-node">&quot;#{l_compare} #{function_hash[&quot;operator&quot;]} #{function_hash[&quot;r_compare&quot;]}&quot;</span>)
316 176:         (<span class="ruby-identifier">result</span>.<span class="ruby-identifier">nil?</span>) <span class="ruby-operator">?</span> <span class="ruby-keyword kw">false</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">result</span>
317 177:       <span class="ruby-keyword kw">end</span>
318 178:     <span class="ruby-keyword kw">end</span>
319 </pre>
320           </div>
321         </div>
322       </div>
323
324       <div id="method-M000145" class="method-detail">
325         <a name="M000145"></a>
326
327         <div class="method-heading">
328           <a href="#M000145" class="method-signature">
329           <span class="method-name">eval_compound_statement</span><span class="method-args">(expression)</span>
330           </a>
331         </div>
332       
333         <div class="method-description">
334           <p>
335 Evaluates a compound statement
336 </p>
337           <p><a class="source-toggle" href="#"
338             onclick="toggleCode('M000145-source');return false;">[Source]</a></p>
339           <div class="method-source-code" id="M000145-source">
340 <pre>
341      <span class="ruby-comment cmt"># File lib/mcollective/matcher.rb, line 115</span>
342 115:     <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">eval_compound_statement</span>(<span class="ruby-identifier">expression</span>)
343 116:       <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">expression</span>.<span class="ruby-identifier">values</span>.<span class="ruby-identifier">first</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/^\//</span>
344 117:         <span class="ruby-keyword kw">return</span> <span class="ruby-constant">Util</span>.<span class="ruby-identifier">has_cf_class?</span>(<span class="ruby-identifier">expression</span>.<span class="ruby-identifier">values</span>.<span class="ruby-identifier">first</span>)
345 118:       <span class="ruby-keyword kw">elsif</span> <span class="ruby-identifier">expression</span>.<span class="ruby-identifier">values</span>.<span class="ruby-identifier">first</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/&gt;=|&lt;=|=|&lt;|&gt;/</span>
346 119:         <span class="ruby-identifier">optype</span> = <span class="ruby-identifier">expression</span>.<span class="ruby-identifier">values</span>.<span class="ruby-identifier">first</span>.<span class="ruby-identifier">match</span>(<span class="ruby-regexp re">/&gt;=|&lt;=|=|&lt;|&gt;/</span>)
347 120:         <span class="ruby-identifier">name</span>, <span class="ruby-identifier">value</span> = <span class="ruby-identifier">expression</span>.<span class="ruby-identifier">values</span>.<span class="ruby-identifier">first</span>.<span class="ruby-identifier">split</span>(<span class="ruby-identifier">optype</span>[<span class="ruby-value">0</span>])
348 121:         <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">value</span>.<span class="ruby-identifier">split</span>(<span class="ruby-value str">&quot;&quot;</span>)[<span class="ruby-value">0</span>] <span class="ruby-operator">==</span> <span class="ruby-value str">&quot;/&quot;</span>
349 122:           <span class="ruby-identifier">optype</span>[<span class="ruby-value">0</span>] <span class="ruby-operator">==</span> <span class="ruby-value str">&quot;=&quot;</span> <span class="ruby-operator">?</span> <span class="ruby-identifier">optype</span> = <span class="ruby-value str">&quot;==&quot;</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">optype</span> = <span class="ruby-identifier">optype</span>[<span class="ruby-value">0</span>]
350 123:         <span class="ruby-keyword kw">else</span>
351 124:           <span class="ruby-identifier">optype</span> = <span class="ruby-value str">&quot;=~&quot;</span>
352 125:         <span class="ruby-keyword kw">end</span>
353 126: 
354 127:         <span class="ruby-keyword kw">return</span> <span class="ruby-constant">Util</span>.<span class="ruby-identifier">has_fact?</span>(<span class="ruby-identifier">name</span>,<span class="ruby-identifier">value</span>, <span class="ruby-identifier">optype</span>).<span class="ruby-identifier">to_s</span>
355 128:       <span class="ruby-keyword kw">else</span>
356 129:         <span class="ruby-keyword kw">return</span> <span class="ruby-constant">Util</span>.<span class="ruby-identifier">has_cf_class?</span>(<span class="ruby-identifier">expression</span>.<span class="ruby-identifier">values</span>.<span class="ruby-identifier">first</span>)
357 130:       <span class="ruby-keyword kw">end</span>
358 131:     <span class="ruby-keyword kw">end</span>
359 </pre>
360           </div>
361         </div>
362       </div>
363
364       <div id="method-M000144" class="method-detail">
365         <a name="M000144"></a>
366
367         <div class="method-heading">
368           <a href="#M000144" class="method-signature">
369           <span class="method-name">execute_function</span><span class="method-args">(function_hash)</span>
370           </a>
371         </div>
372       
373         <div class="method-description">
374           <p>
375 Returns the result of an executed function
376 </p>
377           <p><a class="source-toggle" href="#"
378             onclick="toggleCode('M000144-source');return false;">[Source]</a></p>
379           <div class="method-source-code" id="M000144-source">
380 <pre>
381      <span class="ruby-comment cmt"># File lib/mcollective/matcher.rb, line 78</span>
382  78:     <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">execute_function</span>(<span class="ruby-identifier">function_hash</span>)
383  79:       <span class="ruby-comment cmt"># In the case where a data plugin isn't present there are two ways we can handle</span>
384  80:       <span class="ruby-comment cmt"># the raised exception. The function result can either be false or the entire</span>
385  81:       <span class="ruby-comment cmt"># expression can fail.</span>
386  82:       <span class="ruby-comment cmt">#</span>
387  83:       <span class="ruby-comment cmt"># In the case where we return the result as false it opens us op to unexpected</span>
388  84:       <span class="ruby-comment cmt"># negation behavior.</span>
389  85:       <span class="ruby-comment cmt">#</span>
390  86:       <span class="ruby-comment cmt">#   !foo('bar').name = bar</span>
391  87:       <span class="ruby-comment cmt">#</span>
392  88:       <span class="ruby-comment cmt"># In this case the user would expect discovery to match on all machines where</span>
393  89:       <span class="ruby-comment cmt"># the name value of the foo function does not equal bar. If a non existent function</span>
394  90:       <span class="ruby-comment cmt"># returns false then it is posible to match machines where the name value of the</span>
395  91:       <span class="ruby-comment cmt"># foo function is bar.</span>
396  92:       <span class="ruby-comment cmt">#</span>
397  93:       <span class="ruby-comment cmt"># Instead we raise a DDLValidationError to prevent this unexpected behavior from</span>
398  94:       <span class="ruby-comment cmt"># happening.</span>
399  95: 
400  96:       <span class="ruby-identifier">result</span> = <span class="ruby-constant">Data</span>.<span class="ruby-identifier">send</span>(<span class="ruby-identifier">function_hash</span>[<span class="ruby-value str">&quot;name&quot;</span>], <span class="ruby-identifier">function_hash</span>[<span class="ruby-value str">&quot;params&quot;</span>])
401  97: 
402  98:       <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">function_hash</span>[<span class="ruby-value str">&quot;value&quot;</span>]
403  99:         <span class="ruby-keyword kw">begin</span>
404 100:           <span class="ruby-identifier">eval_result</span> = <span class="ruby-identifier">result</span>.<span class="ruby-identifier">send</span>(<span class="ruby-identifier">function_hash</span>[<span class="ruby-value str">&quot;value&quot;</span>])
405 101:         <span class="ruby-keyword kw">rescue</span>
406 102:           <span class="ruby-comment cmt"># If data field has not been set we set the comparison result to nil</span>
407 103:           <span class="ruby-identifier">eval_result</span> = <span class="ruby-keyword kw">nil</span>
408 104:         <span class="ruby-keyword kw">end</span>
409 105:         <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">eval_result</span>
410 106:       <span class="ruby-keyword kw">else</span>
411 107:         <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">result</span>
412 108:       <span class="ruby-keyword kw">end</span>
413 109:     <span class="ruby-keyword kw">rescue</span> <span class="ruby-constant">NoMethodError</span>
414 110:       <span class="ruby-constant">Log</span>.<span class="ruby-identifier">debug</span>(<span class="ruby-node">&quot;cannot execute discovery function '#{function_hash[&quot;name&quot;]}'. data plugin not found&quot;</span>)
415 111:       <span class="ruby-identifier">raise</span> <span class="ruby-constant">DDLValidationError</span>
416 112:     <span class="ruby-keyword kw">end</span>
417 </pre>
418           </div>
419         </div>
420       </div>
421
422
423     </div>
424
425
426   </div>
427
428
429 <div id="validator-badges">
430   <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
431 </div>
432
433 </body>
434 </html>