/usr/share/doc/gnat-gps/html/Subprogram-parameters.html is in gnat-gps-doc 5.0-6.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | <html lang="en">
<head>
<title>Subprogram parameters - Using the GNAT Programming Studio</title>
<meta http-equiv="Content-Type" content="text/html">
<meta name="description" content="Using the GNAT Programming Studio">
<meta name="generator" content="makeinfo 4.13">
<link title="Top" rel="start" href="index.html#Top">
<link rel="up" href="Scripting-GPS.html#Scripting-GPS" title="Scripting GPS">
<link rel="prev" href="The-Python-Interpreter.html#The-Python-Interpreter" title="The Python Interpreter">
<link rel="next" href="Python-FAQ.html#Python-FAQ" title="Python FAQ">
<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
<!--
Copyright (C) 2002-2010 AdaCore.
This document is free; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This document is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, see `http://www.gnu.org/licenses/'.-->
<meta http-equiv="Content-Style-Type" content="text/css">
<style type="text/css"><!--
pre.display { font-family:inherit }
pre.format { font-family:inherit }
pre.smalldisplay { font-family:inherit; font-size:smaller }
pre.smallformat { font-family:inherit; font-size:smaller }
pre.smallexample { font-size:smaller }
pre.smalllisp { font-size:smaller }
span.sc { font-variant:small-caps }
span.roman { font-family:serif; font-weight:normal; }
span.sansserif { font-family:sans-serif; font-weight:normal; }
pre.smallexample {background-color:rgb(240,240,240);
font-family: courier new,courier,fixed;
font-size: 14px;
margin: 0px 40px 0px 40px;
border-width: 1px 2px 2px 1px;
border-top-style: dotted;
border-left-style: dotted;
border-right-style: solid;
border-bottom-style: solid;
border-color: black;}
code {color:black;
font-family: courier new,courier,fixed;
font-size: 14px;}
body {font-family: arial,helvetica,sans-serif;
font-size: 16px;
max-width: 800px;
text-align: justify}
samp {font-family: courier new,courier,fixed;
font-size: 14px}
--></style>
</head>
<body>
<div class="node">
<a name="Subprogram-parameters"></a>
<p>
Next: <a rel="next" accesskey="n" href="Python-FAQ.html#Python-FAQ">Python FAQ</a>,
Previous: <a rel="previous" accesskey="p" href="The-Python-Interpreter.html#The-Python-Interpreter">The Python Interpreter</a>,
Up: <a rel="up" accesskey="u" href="Scripting-GPS.html#Scripting-GPS">Scripting GPS</a>
<hr>
</div>
<h4 class="subsection">16.8.6 Subprogram parameters</h4>
<p><a name="index-subprogram-parameters-896"></a><!-- -->
<p class="noindent">A few of the functions exported by GPS in the GPS shell or in python expect
a subprogram as a parameter.
<p>This is handled in different ways depending on what language your are using:
<ul>
<li>GPS shell
<p>It isn't possible to define new functions in the GPS shell. However, this
concept is similar to the GPS actions (see <a href="Defining-Actions.html#Defining-Actions">Defining Actions</a>), which
allow you to execute a set of commands and launch external processes.
<p>Therefore, a subprogram parameter in the GPS shell is a string, which is the
name of the action to execute.
<p>For instance, the following code defines the action "on_edition",
which is called every time a new file is edited. The action is defined
in the shell itself, although this could be more conveniently done in
a separate customization file.
<pre class="smallexample"> parse_xml """<action name="on_edition">
<shell>echo "File edited"</shell></action>"""
Hook "file_edited"
Hook.add %1 "on_edition"
</pre>
<li>Python
<p>Python of course has its own notion of subprogram, and GPS is fully compatible
with it. As a result, the syntax is much more natural than in the GPS shell.
The following example has the same result as above:
<pre class="smallexample"> import GPS
def on_edition(self, *arg):
print "File edited"
GPS.Hook ("file_edited").add (on_edition)
</pre>
<p>Things are in fact slightly more complex if you want to pass methods
as arguments. Python has basically three notions of callable
subprograms, detailed below. The following examples all create a combo
box in the toolbar, which calls a subprogram whenever its value is
changed. The documentation for the combo box indicates that the
callback in this case takes two parameters:
<ul>
<li>The instance of the combo
<li>The current selection in the combo box
</ul>
<p>The first parameter is the instance of the combo box associated with
the toolbar widget, and, as always in python, you can store your own
data in the instance, as shown in the examples below.
<p>Here is the description of the various subprograms:
<ul>
<li>Global subprograms
<p>These are standard subprograms, found outside class definitions. There
is no implicit parameter in this case. However, if you need to pass
data to such a subprogram, you need to use global variables
<pre class="smallexample"> import GPS
my_var = "global data"
def on_changed (combo, choice):
global my_var
print "on_changed called: " + \
my_var + " " + combo.data + " " + choice
combo = GPS.Combo \
("name", label="name", on_changed=on_changed)
GPS.Toolbar().append (combo)
combo.data = "My own data"
</pre>
<li>Unbound methods
<p>These are methods of a class. You do not specify, when you pass the
method in parameter to the combo box, what instance should be passed
as its first parameter. Therefore, there is no extra parameter either.
<p>Note however than whatever class the method is defined in, the first
parameter is always an instance of the class documented in the GPS
documentation (in this case a GPS.Combo instance), not an
instance of the current class.
<p>In this first example, since we do not have access to the instance of
MyClass, we also need to store the global data as a class
component. This is a problem if multiple instances of the class can
be created.
<pre class="smallexample"> import GPS
class MyClass:
my_var = "global data"
def __init__ (self):
self.combo = GPS.Combo \
("name", label="name", on_changed=MyClass.on_changed)
GPS.Toolbar().append (self.combo)
self.combo.data = "My own data"
def on_changed (combo, choice):
## No direct access to the instance of MyClass.
print "on_changed called: " + \
MyClass.my_var + " " + combo.data + " " + choice
MyClass()
</pre>
<p>As the example above explains, there is no direct access to MyClass
when executing on_changed. An easy workaround is the following, in
which the global data can be stored in the instance of MyClass,
and thus be different for each instance of MyClass.
<pre class="smallexample"> import GPS
class MyClass:
def __init__ (self):
self.combo = GPS.Combo \
("name", label="name", on_changed=MyClass.on_changed)
GPS.Toolbar().append (self.combo)
self.combo.data = "My own data"
self.combo.myclass = self ## Save the instance
self.my_var = "global data"
def on_changed (combo, choice):
print "on_changed called: " + \
combo.myclass.my_var + " " + combo.data + " " + choice
MyClass()
</pre>
<li>Bound methods
<p>The last example works as expected, but is not convenient to use. The
solution here is to use a bound method, which is a method for a
specific instance of a class. Such a method always has an extra first
parameter, set implicitly by Python or GPS, which is the instance of
the class the method is defined in.
<p>Notice the way we pass the method in parameter to append(), and the
extra third argument to on_changed in the example below.
<pre class="smallexample"> import GPS
class MyClass:
def __init__ (self):
self.combo = GPS.Combo \
("name", label="name", on_changed=self.on_changed)
GPS.Toolbar().append (self.combo)
self.combo.data = "My own data"
self.my_var = "global data"
def on_changed (self, combo, choice):
# self is the instance of MyClass specified in call to append()
print "on_changed called: " + \
self.my_var + " " + combo.data + " " + choice
MyClass()
</pre>
<p>It is often convenient to use the object-oriented approach when writing
python scripts. If for instance you want to spawn an external process,
GPS provides the <code>GPS.Process</code> class. When you create an instance,
you specify a callback to be called when some input is made available
by the process. Matching the above example, the code would look something
like:
<pre class="smallexample"> class MyClass:
def __init__ (self):
self.process = GPS.Process
("command_line", on_match = self.on_match)
def on_match (self, process, matched, unmatched);
print "Process output: " + unmatched + matched + "\n"
</pre>
<p>A more natural approach, rather than having a class that has a process
field, is to directly extend the <code>GPS.Process</code> class, as in:
<pre class="smallexample"> class MyClass (GPS.Process):
def __init__ (self):
GPS.Process.__init__ \
(self, "command_line", on_match = self.on_match)
def on_match (self, matched, unmatched);
print "Process output: " + unmatched + matched + "\n"
</pre>
<p>Any command that can be used on a process (such as <code>send</code>) can then
directly be used on instances of MyClass.
<p>There is one non-obvious improvement in the code above: the <code>on_match</code>
callback has one less parameter. What happens is the following: as per
the documentation of <code>GPS.Process.__init__</code>, GPS gives three arguments
to its <code>on_match</code> callback: the instance of the process (<code>process</code>
in the first example above), the string that matched the regular expression,
and the string before that match.
<p>In the first example above, we are passing <code>self.on_match</code>, ie a
bound method, as a callback. That tells python that it should automatically,
and transparently, add an extra first parameter when calling
<code>MyClass.on_match</code>, which is <code>self</code>. This is why the first example
has four parameters to <code>on_match</code>.
<p>However, the second example only has three parameters, because GPS has
detected that <code>self</code> (the instance of <code>MyClass</code>) and the
instance of <code>GPS.Process</code> are the same in this case. Thus it doesn't
add an extra parameter (<code>self</code> and <code>process</code> would have been
the same).
</ul>
</ul>
<!-- -->
</body></html>
|