ruby-dbus 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS +16 -0
- data/README +1 -1
- data/Rakefile +20 -10
- data/VERSION +1 -1
- data/lib/dbus/auth.rb +11 -5
- data/lib/dbus/bus.rb +57 -27
- data/lib/dbus/export.rb +9 -6
- data/lib/dbus/introspect.rb +24 -42
- data/lib/dbus/marshall.rb +20 -19
- data/lib/dbus/matchrule.rb +2 -1
- data/lib/dbus/message.rb +1 -1
- data/ruby-dbus.gemspec +2 -0
- data/test/binding_test.rb +1 -1
- data/test/bus_driver_test.rb +1 -1
- data/test/bus_test.rb +18 -0
- data/test/property_test.rb +1 -1
- data/test/server_robustness_test.rb +3 -3
- data/test/server_test.rb +1 -1
- data/test/service_newapi.rb +9 -1
- data/test/session_bus_test_manual.rb +1 -1
- data/test/signal_test.rb +1 -1
- data/test/t2.rb +7 -1
- data/test/t3-ticket27.rb +1 -1
- data/test/t5-report-dbus-interface.rb +1 -1
- data/test/t6-loop.rb +1 -1
- data/test/thread_safety_test.rb +35 -0
- data/test/variant_test.rb +1 -1
- metadata +15 -13
- data/doc/tutorial/index.html +0 -365
- data/examples/no-introspect/call-overloaded.rb +0 -22
data/doc/tutorial/index.html
DELETED
@@ -1,365 +0,0 @@
|
|
1
|
-
<style>
|
2
|
-
code { background-color: #F0E7E7; }
|
3
|
-
pre code { background-color: #F0DDDD; }
|
4
|
-
pre {
|
5
|
-
font-size: 90%;
|
6
|
-
overflow: hidden;
|
7
|
-
padding-left: 10pt;
|
8
|
-
border: thin solid #F0B4B4;
|
9
|
-
background-color: #F0DDDD;
|
10
|
-
}
|
11
|
-
</style>
|
12
|
-
|
13
|
-
<h1>Welcome</h1>
|
14
|
-
<p>This is the Ruby D-Bus tutorial. It aims to show you the features of Ruby
|
15
|
-
D-Bus and as you read through the tutorial also how to use them.</p>
|
16
|
-
<p>© Arnaud Cornet and Paul van Tilburg; this tutorial is part of
|
17
|
-
free software; you can redistribute it and/or modify it under the
|
18
|
-
terms of the <a href="http://www.gnu.org/licenses/lgpl.html">GNU Lesser General Public License,
|
19
|
-
version 2.1</a> as published by the
|
20
|
-
<a href="http://www.fsf.org/">Free Software Foundation</a>.</p>
|
21
|
-
<h1>Introduction</h1>
|
22
|
-
<p>This is a tutorial for Ruby D-Bus, a library to access D-Bus facilities of your
|
23
|
-
system.</p>
|
24
|
-
<h2>What is D-Bus?</h2>
|
25
|
-
<p>D-Bus is an RPC(Remote Procedure Call) protocol. A common setup can have
|
26
|
-
multiple D-Bus daemons running that route procedure calls and signals in
|
27
|
-
the form of messages. Each of these daemons supports a bus. A bus that
|
28
|
-
is often used by modern desktop environments, and is available per session, is
|
29
|
-
called the <em>session bus</em>. Another bus that can be available, but in a
|
30
|
-
system-wide manner, is called the <em>system bus</em>. It is used for example by
|
31
|
-
the <a href="http://hal.freedesktop.org/">Hardware Abstraction Layer</a> daemon. Note
|
32
|
-
that theoretically the D-Bus RPC protocol can be used without a system or
|
33
|
-
session bus. I never came across any actual use of this though.</p>
|
34
|
-
<p>At the desktop level, D-Bus allows some components to interact. Typically
|
35
|
-
if you are writing an application or a personal script that wants to
|
36
|
-
interact with your web browser, your music player, or that simply wants to
|
37
|
-
pop-up a desktop notification, D-Bus comes into play.</p>
|
38
|
-
<p>At the system level, the Hardware Abstraction Layer is a privileged daemon
|
39
|
-
that notifies other software of hardware activities. Typically, if you
|
40
|
-
want to be notified if a CD-ROM has been loaded in, of if you want to
|
41
|
-
explore hardware, the system daemon comes into play.</p>
|
42
|
-
<p>The D-Bus RPC system is as we will see <em>object oriented</em>.</p>
|
43
|
-
<p>Buses provide access to <em>services</em> provided in turn by running or ready to
|
44
|
-
run processes. Let me introduce some D-Bus terminology before we discuss
|
45
|
-
the API of Ruby D-Bus.</p>
|
46
|
-
<h2>Client</h2>
|
47
|
-
<p>A D-Bus client is a process that connects to a D-Bus. They issue method
|
48
|
-
calls and register to the bus for signals and events.</p>
|
49
|
-
<h2>Service</h2>
|
50
|
-
<p>A connected client can export some of its objects and let other clients
|
51
|
-
call some of its methods. Such clients typically register a special name
|
52
|
-
like <code>org.freedesktop.Notifications</code>, the service name.</p>
|
53
|
-
<p>There is slightly different type of service. They are provided by
|
54
|
-
processes that can be launched by a D-Bus daemon on demand. Once they are
|
55
|
-
started by D-Bus they register a service name and behave like another
|
56
|
-
client.</p>
|
57
|
-
<p>Note that the buses themselves provide the <code>org.freedesktop.DBus</code> service,
|
58
|
-
and provide some features through it.</p>
|
59
|
-
<h2>Object path</h2>
|
60
|
-
<p>An object path is the D-Bus way to specify an object <em>instance</em> address. A
|
61
|
-
service can provide different object instances to the outside world, so
|
62
|
-
that external processes can call methods on each of them. An object path
|
63
|
-
is an address of an instance in a very similar way that the path is an
|
64
|
-
address of a file on a file system. For example:
|
65
|
-
<code>/org/freedesktop/Notification</code> is an object path of an object provided by
|
66
|
-
the <code>org.freedesktop.Notification</code> service</p>
|
67
|
-
<p><strong>Beware</strong>: service names and object paths can, but do <em>not</em> have to be
|
68
|
-
related! You'll probably encounter a lot of cases though, where the
|
69
|
-
object path is a slashed version of the dotted service name.</p>
|
70
|
-
<h2>Interface</h2>
|
71
|
-
<p>Classically in an object model, classes can implement interfaces. That is,
|
72
|
-
some method definitions grouped in an interface. This is exactly what a
|
73
|
-
D-Bus interface is as well. In D-Bus interfaces have names. These names must be
|
74
|
-
specified on method calls.</p>
|
75
|
-
<p>The <code>org.freedesktop.Notification</code> service provides an object instance
|
76
|
-
called <code>/org/freedesktop/Notification</code>. This instance object implements an
|
77
|
-
interface called <code>org.freedesktop.Notifications</code>. It also provides two
|
78
|
-
special D-Bus specific interfaces: <code>org.freedesktop.DBus.Introspect</code> and
|
79
|
-
<code>org.freedesktop.DBus.Properties</code>. Again, object paths, service names,
|
80
|
-
and interface names can be related but do not have to be.</p>
|
81
|
-
<p>Basically the <code>org.freedesktop.DBus.Introspect</code> has an <code>Introspect</code> method,
|
82
|
-
that returns XML data describing the <code>/org/freedesktop/Notification</code> object
|
83
|
-
interfaces. This is used heavily internally by Ruby D-Bus.</p>
|
84
|
-
<h2>Method</h2>
|
85
|
-
<p>A method is, well, a method in the classical meaning. It's a function that
|
86
|
-
is called in the context of an object instance. Methods have typed
|
87
|
-
parameters and return typed return values.</p>
|
88
|
-
<h2>Signal</h2>
|
89
|
-
<p>Signals are simplified method calls that do not have a return value. They
|
90
|
-
do have typed parameters though.</p>
|
91
|
-
<h2>Message</h2>
|
92
|
-
<p>Method calls, method returns, signals, errors: all are encoded as D-Bus
|
93
|
-
messages sent over a bus. They are made of a packet header with source and
|
94
|
-
destination address, a type (method call, method reply, signal) and the
|
95
|
-
body containing the parameters (for signals and method calls) or the return
|
96
|
-
values (for a method return message).</p>
|
97
|
-
<h2>Signature</h2>
|
98
|
-
<p>Because D-Bus is typed and dynamic, each message comes with a signature that
|
99
|
-
describes the types of the data that is contained within the message. The
|
100
|
-
signature is a string with an extremely basic language that only describes
|
101
|
-
a data type. You will need to have some knowledge of what a signature
|
102
|
-
looks like if you are setting up a service. If you are just programming a
|
103
|
-
D-Bus client, you can live without knowing about them.</p>
|
104
|
-
<h1>Client Usage</h1>
|
105
|
-
<p>This chapter discusses basic client usage
|
106
|
-
and has the following topics:</p>
|
107
|
-
<h2>Using the library</h2>
|
108
|
-
<p>If you want to use the library, you have to make Ruby load it by issuing:</p>
|
109
|
-
<pre><code>require 'dbus'
|
110
|
-
</code></pre>
|
111
|
-
<p>That's all! Now we can move on to really using it...</p>
|
112
|
-
<h2>Connecting to a bus</h2>
|
113
|
-
<p>On a typical system, two buses are running, the system bus and the session
|
114
|
-
bus. The system bus can be accessed by:</p>
|
115
|
-
<pre><code>bus = DBus::SystemBus.instance
|
116
|
-
</code></pre>
|
117
|
-
<p>Probably you already have guessed how to access the session bus. This
|
118
|
-
can be done by:</p>
|
119
|
-
<pre><code>bus = DBus::SessionBus.instance
|
120
|
-
</code></pre>
|
121
|
-
<h2>Performing method calls</h2>
|
122
|
-
<p>Let me continue this example using the session bus. Let's say that I want
|
123
|
-
to access an object of some client on the session bus. This particular
|
124
|
-
D-Bus client provides a service called <code>org.gnome.Rhythmbox</code>. Let me
|
125
|
-
access this service:</p>
|
126
|
-
<pre><code>rb_service = bus.service("org.gnome.Rhythmbox")
|
127
|
-
</code></pre>
|
128
|
-
<p>In this example I access the <code>org.gnome.Rhythmbox</code> service, which is
|
129
|
-
provided by the application
|
130
|
-
<a href="http://www.gnome.org/projects/rhythmbox/">Rhythmbox</a>.
|
131
|
-
OK, I have a service handle now, and I know that it exports the object
|
132
|
-
"/org/gnome/Rhythmbox/Player". I will trivially access this remote object
|
133
|
-
using:</p>
|
134
|
-
<pre><code>rb_player = rb_service.object("/org/gnome/Rhythmbox/Player")
|
135
|
-
</code></pre>
|
136
|
-
<h2>Introspection</h2>
|
137
|
-
<p>Well, that was easy. Let's say that I know that this particular object is
|
138
|
-
introspectable. In real life most of them are. The <code>rb_object</code> object we
|
139
|
-
have here is just a handle of a remote object, in general they are called
|
140
|
-
<em>proxy objects</em>, because they are the local handle of a remote object. It
|
141
|
-
would be nice to be able to make it have methods, and that its methods send
|
142
|
-
a D-Bus call to remotely execute the actual method in another process.
|
143
|
-
Well, instating these methods for a <em>introspectable</em> object is trivial:</p>
|
144
|
-
<pre><code>rb_player.introspect
|
145
|
-
</code></pre>
|
146
|
-
<p>And there you go. Note that not all services or objects can be
|
147
|
-
introspected, therefore you have to do this manually! Let me remind you
|
148
|
-
that objects in D-Bus have interfaces and interfaces have methods. Let's
|
149
|
-
now access these methods:</p>
|
150
|
-
<pre><code>rb_player_iface = rb_player["org.gnome.Rhythmbox.Player"]
|
151
|
-
puts rb_player_iface.getPlayingUri
|
152
|
-
</code></pre>
|
153
|
-
<p>As you can see, when you want to call a method on an instance object, you have
|
154
|
-
to get the correct interface. It is a bit tedious, so we have the following
|
155
|
-
shortcut that does the same thing as before:</p>
|
156
|
-
<pre><code>rb_player.default_iface = "org.gnome.Rhythmbox.Player"
|
157
|
-
puts rb_player.getPlayingUri
|
158
|
-
</code></pre>
|
159
|
-
<p>The <code>default_iface=</code> call specifies the default interface that should be
|
160
|
-
used when non existing methods are called directly on a proxy object, and
|
161
|
-
not on one of its interfaces.</p>
|
162
|
-
<p>Note that the bus itself has a corresponding introspectable object. You can
|
163
|
-
access it with <code>bus.proxy</code> method. For example, you can retrieve an array of
|
164
|
-
exported service names of a bus like this:</p>
|
165
|
-
<pre><code>bus.proxy.ListNames[0]
|
166
|
-
</code></pre>
|
167
|
-
<h2>Properties</h2>
|
168
|
-
<p>Some D-Bus objects provide access to properties. They are accessed by
|
169
|
-
treating a proxy interface as a hash:</p>
|
170
|
-
<pre><code>nm_iface = network_manager_object["org.freedesktop.NetworkManager"]
|
171
|
-
enabled = nm_iface["WirelessEnabled"]
|
172
|
-
puts "Wireless is " + (enabled ? "enabled":"disabled")
|
173
|
-
puts "Toggling wireless"
|
174
|
-
nm_iface["WirelessEnabled"] = ! enabled
|
175
|
-
</code></pre>
|
176
|
-
<h2>Calling a method asynchronously</h2>
|
177
|
-
<p>D-Bus is <em>asynchronous</em>. This means that you do not have to wait for a
|
178
|
-
reply when you send a message. When you call a remote method that takes a
|
179
|
-
lot of time to process remotely, you don't want your application to hang,
|
180
|
-
right? Well the asychronousness exists for this reason. What if you dont'
|
181
|
-
want to wait for the return value of a method, but still you want to take
|
182
|
-
some action when you receive it?</p>
|
183
|
-
<p>There is a classical method to program this event-driven mechanism. You do
|
184
|
-
some computation, perform some method call, and at the same time you setup
|
185
|
-
a callback that will be triggered once you receive a reply. Then you run a
|
186
|
-
main loop that is responsible to call the callbacks properly. Here is how
|
187
|
-
you do it:</p>
|
188
|
-
<pre><code>rb_player.getPlayingUri do |resp|
|
189
|
-
puts "The playing URI is #{resp}"
|
190
|
-
end
|
191
|
-
puts "See, I'm not waiting!"
|
192
|
-
loop = DBus::Main.new
|
193
|
-
loop << bus
|
194
|
-
loop.run
|
195
|
-
</code></pre>
|
196
|
-
<p>This code will print the following:</p>
|
197
|
-
<pre><code>See, I'm not waiting!
|
198
|
-
The playing URI is file:///music/papapingoin.mp3
|
199
|
-
</code></pre>
|
200
|
-
<h2>Waiting for a signal</h2>
|
201
|
-
<p>Signals are calls from the remote object to your program. As a client, you
|
202
|
-
set yourself up to receive a signal and handle it with a callback. Then running
|
203
|
-
the main loop triggers the callback. You can register a callback handler
|
204
|
-
as allows:</p>
|
205
|
-
<pre><code>rb_player.on_signal("elapsedChanged") do |u|
|
206
|
-
puts u
|
207
|
-
end
|
208
|
-
</code></pre>
|
209
|
-
<h2>More about introspection</h2>
|
210
|
-
<p>There are various ways to inspect a remote service. You can simply call
|
211
|
-
<code>Introspect()</code> and read the XML output. However, in this tutorial I assume
|
212
|
-
that you want to do it using the Ruby D-Bus API.</p>
|
213
|
-
<p>Notice that you can introspect a service, and not only objects:</p>
|
214
|
-
<pre><code>rb_service = bus.service("org.gnome.Rhythmbox")
|
215
|
-
rb_service.introspect
|
216
|
-
p rb_service.root
|
217
|
-
</code></pre>
|
218
|
-
<p>This dumps a tree-like structure that represents multiple object paths. In
|
219
|
-
this particular case the output is:</p>
|
220
|
-
<pre><code></: {org => {gnome => {Rhythmbox => {Player => ..fdbe625de {},Shell => ..fdbe6852e {},PlaylistManager => ..fdbe4e340 {}}>
|
221
|
-
</code></pre>
|
222
|
-
<p>Read this left to right: the root node is "/", it has one child node "org",
|
223
|
-
"org" has one child node "gnome", and "gnome" has one child node "Rhythmbox".
|
224
|
-
Rhythmbox has Tree child nodes "Player", "Shell" and "PlaylistManager".
|
225
|
-
These three last child nodes have a weird digit that means it has an object
|
226
|
-
instance. Such object instances are already introspected.</p>
|
227
|
-
<p>If the prose wasn't clear, maybe the following ASCII art will help you:</p>
|
228
|
-
<pre><code>/
|
229
|
-
org
|
230
|
-
gnome
|
231
|
-
Rhythmbox
|
232
|
-
Shell (with object)
|
233
|
-
Player (with object)
|
234
|
-
PlaylistManager (with object)
|
235
|
-
</code></pre>
|
236
|
-
<h3>Walking the object tree</h3>
|
237
|
-
<p>You can have an object on any node, i.e. it is not limited to leaves.
|
238
|
-
You can access a specific node like this:</p>
|
239
|
-
<pre><code>rb_player = rb_service.root["org"]["gnome"]["Rhythmbox"]["Player"]
|
240
|
-
rb_player = rb_service.object("/org/gnome/Rhythmbox/Player")
|
241
|
-
</code></pre>
|
242
|
-
<p>The difference between the two is that for the first one, <code>rb_service</code>
|
243
|
-
needs to have been introspected. Also the obtained <code>rb_player</code> is already
|
244
|
-
introspected whereas the second <code>rb_player</code> isn't yet.</p>
|
245
|
-
<h2>Errors</h2>
|
246
|
-
<p>D-Bus calls can reply with an error instead of a return value. An error is
|
247
|
-
translated to a Ruby exception.</p>
|
248
|
-
<pre><code>begin
|
249
|
-
network_manager.sleep
|
250
|
-
rescue DBus::Error => e
|
251
|
-
puts e unless e.name == "org.freedesktop.NetworkManager.AlreadyAsleepOrAwake"
|
252
|
-
end
|
253
|
-
</code></pre>
|
254
|
-
<h1>Creating a Service</h1>
|
255
|
-
<p>This chapter deals with the opposite side of the basic client usage, namely
|
256
|
-
the creation of a D-Bus service.</p>
|
257
|
-
<h2>Registering a service</h2>
|
258
|
-
<p>Now that you know how to perform D-Bus calls, and how to wait for and
|
259
|
-
handle signals, you might want to learn how to publish some object and
|
260
|
-
interface to provide them to the D-Bus world. Here is how you do that.</p>
|
261
|
-
<p>As you should already know, D-Bus clients that provide some object to be
|
262
|
-
called remotely are services. Here is how to allocate a name on a bus:</p>
|
263
|
-
<pre><code>bus = DBus.session_bus
|
264
|
-
service = bus.request_service("org.ruby.service")
|
265
|
-
</code></pre>
|
266
|
-
<p>Now this client is know to the outside world as <code>org.ruby.service</code>.
|
267
|
-
Note that this is a request and it <em>can</em> be denied! When it
|
268
|
-
is denied, an exception (<code>DBus::NameRequestError</code>) is thrown.</p>
|
269
|
-
<h2>Exporting an object</h2>
|
270
|
-
<p>Now, let's define a class that we want to export:</p>
|
271
|
-
<pre><code>class Test < DBus::Object
|
272
|
-
# Create an interface.
|
273
|
-
dbus_interface "org.ruby.SampleInterface" do
|
274
|
-
# Create a hello method in that interface.
|
275
|
-
dbus_method :hello, "in name:s, in name2:s" do |name, name2|
|
276
|
-
puts "hello(#{name}, #{name2})"
|
277
|
-
end
|
278
|
-
end
|
279
|
-
end
|
280
|
-
</code></pre>
|
281
|
-
<p>As you can see, we define a <code>Test</code> class in which we define a
|
282
|
-
<code>org.ruby.SampleInterface</code> interface. In this interface, we define a
|
283
|
-
method. The given code block is the method's implementation. This will be
|
284
|
-
executed when remote programs performs a D-Bus call. Now the annoying part:
|
285
|
-
the actual method definition. As you can guess the call</p>
|
286
|
-
<pre><code>dbus_method :hello, "in name:s, in name2:s" do ...
|
287
|
-
</code></pre>
|
288
|
-
<p>creates a <code>hello</code> method that takes two parameters both of type string.
|
289
|
-
The <em>:s</em> means "of type string". Let's have a look at some other common
|
290
|
-
parameter types:</p>
|
291
|
-
<ul>
|
292
|
-
<li><em>u</em> means unsigned integer</li>
|
293
|
-
<li><em>i</em> means integer</li>
|
294
|
-
<li><em>y</em> means byte</li>
|
295
|
-
<li><em>(ui)</em> means a structure having a unsigned integer and a signed one.</li>
|
296
|
-
<li><em>a</em> means array, so that "ai" means array of integers<ul>
|
297
|
-
<li><em>as</em> means array of string</li>
|
298
|
-
<li><em>a(is)</em> means array of structures, each having an integer and a string.</li>
|
299
|
-
</ul>
|
300
|
-
</li>
|
301
|
-
</ul>
|
302
|
-
<p>For a full description of the available D-Bus types, please refer to the
|
303
|
-
<a href="http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-signatures">D-Bus specification</a>.</p>
|
304
|
-
<p>Now that the class has been defined, we can instantiate an object
|
305
|
-
and export it as follows:</p>
|
306
|
-
<pre><code>exported_obj = Test.new("/org/ruby/MyInstance")
|
307
|
-
service.export(exported_obj)
|
308
|
-
</code></pre>
|
309
|
-
<p>This piece of code above instantiates a <code>Test</code> object with a D-Bus object
|
310
|
-
path. This object is reachable from the outside world after
|
311
|
-
<code>service.export(exported_obj)</code> is called.</p>
|
312
|
-
<p>We also need a loop which will read and process the calls coming over the bus:</p>
|
313
|
-
<pre><code>loop = DBus::Main.new
|
314
|
-
loop << bus
|
315
|
-
loop.run
|
316
|
-
</code></pre>
|
317
|
-
<h3>Using the exported object</h3>
|
318
|
-
<p>Now, let's consider another program that will access our newly created service:</p>
|
319
|
-
<pre><code>ruby_service = bus.service("org.ruby.service")
|
320
|
-
obj = ruby_service.object("/org/ruby/MyInstance")
|
321
|
-
obj.introspect
|
322
|
-
obj.default_iface = "org.ruby.SampleInterface"
|
323
|
-
obj.hello("giligiligiligili", "haaaaaaa")
|
324
|
-
</code></pre>
|
325
|
-
<p>As you can see, the object we defined earlier is automatically introspectable.
|
326
|
-
See also "Basic Client Usage".</p>
|
327
|
-
<h2>Emitting a signal</h2>
|
328
|
-
<p>Let's add some example method so you can see how to return a value to the
|
329
|
-
caller and let's also define another example interface that has a signal.</p>
|
330
|
-
<pre><code>class Test2 < DBus::Object
|
331
|
-
# Create an interface
|
332
|
-
dbus_interface "org.ruby.SampleInterface" do
|
333
|
-
# Create a hello method in the interface:
|
334
|
-
dbus_method :hello, "in name:s, in name2:s" do |name, name2|
|
335
|
-
puts "hello(#{name}, #{name2})"
|
336
|
-
end
|
337
|
-
# Define a signal in the interface:
|
338
|
-
dbus_signal :SomethingJustHappened, "toto:s, tutu:u"
|
339
|
-
end
|
340
|
-
|
341
|
-
dbus_interface "org.ruby.AnotherInterface" do
|
342
|
-
dbus_method :ThatsALongMethodNameIThink, "in name:s, out ret:s" do |name|
|
343
|
-
["So your name is #{name}"]
|
344
|
-
end
|
345
|
-
end
|
346
|
-
end
|
347
|
-
</code></pre>
|
348
|
-
<p>Triggering the signal is a easy as calling a method, but then this time on
|
349
|
-
a local (exported) object and not on a remote/proxy object:</p>
|
350
|
-
<pre><code>exported_obj.SomethingJustHappened("blah", 1)
|
351
|
-
</code></pre>
|
352
|
-
<p>Note that the <code>ThatsALongMethodNameIThink</code> method is returning a single
|
353
|
-
value to the caller. Notice that you always have to return an array. If
|
354
|
-
you want to return multiple values, just have an array with multiple
|
355
|
-
values.</p>
|
356
|
-
<h2>Replying with an error</h2>
|
357
|
-
<p>To reply to a dbus_method with a D-Bus error, raise a <code>DBus::Error</code>,
|
358
|
-
as constructed by the <code>error</code> convenience function:</p>
|
359
|
-
<pre><code>raise DBus.error("org.example.Error.SeatOccupied"), "Seat #{seat} is occupied"
|
360
|
-
</code></pre>
|
361
|
-
<p>If the error name is not specified, the generic
|
362
|
-
<code>org.freedesktop.DBus.Error.Failed</code> is used.</p>
|
363
|
-
<pre><code>raise DBus.error, "Seat #{seat} is occupied"
|
364
|
-
raise DBus.error
|
365
|
-
</code></pre>
|
@@ -1,22 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
#
|
3
|
-
# How to call overloaded methods.
|
4
|
-
|
5
|
-
require 'dbus'
|
6
|
-
|
7
|
-
bus = DBus::SessionmBus.instance
|
8
|
-
|
9
|
-
konsole_svc = bus["org.freedesktop.konsole"]
|
10
|
-
konsole_obj = konsole_svc["/Konsole"]
|
11
|
-
poi = DBus::ProxyObjectInterface.new(konsole_obj, "org.kde.konsole.Konsole")
|
12
|
-
|
13
|
-
|
14
|
-
begin
|
15
|
-
poi.define_method("getDevices", "") # NM 0.6
|
16
|
-
p poi.getDevices
|
17
|
-
rescue Exception
|
18
|
-
poi.define_method("GetDevices", "") # NM 0.7
|
19
|
-
p poi.GetDevices
|
20
|
-
end
|
21
|
-
|
22
|
-
|