ruby-dbus 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/NEWS
CHANGED
@@ -5,6 +5,22 @@ Note about bug numbers:
|
|
5
5
|
Issue#1 - http://github.com/mvidner/ruby-dbus/issues#issue/1
|
6
6
|
bnc#1 - https://bugzilla.novell.com/show_bug.cgi?id=1
|
7
7
|
|
8
|
+
== Ruby D-Bus 0.7.0 - 2011-07-26
|
9
|
+
|
10
|
+
Features:
|
11
|
+
* Added ASystemBus and ASessionBus, non-singletons useful in tests
|
12
|
+
and threads.
|
13
|
+
|
14
|
+
Bug fixes:
|
15
|
+
* Fixed handling of multibyte strings (Issue#8, by Takayuki YAMAGUCHI).
|
16
|
+
* Allow reopening of a dbus_interface declaration (Issue#9, by T. YAMAGUCHI).
|
17
|
+
* Fixed ruby-1.9.2 compatibility again (Issue#12).
|
18
|
+
* Fixed authentication on BSD (Issue#11, by Jonathan Walker)
|
19
|
+
* Fixed exiting a nested event loop for synchronous calls
|
20
|
+
(reported by Timo Warns).
|
21
|
+
* Fixed introspection calls leaking reply handlers.
|
22
|
+
* "rake test" now works, doing what was called "rake env:test"
|
23
|
+
|
8
24
|
== Ruby D-Bus 0.6.0 - 2010-12-11
|
9
25
|
|
10
26
|
Features:
|
data/README
CHANGED
data/Rakefile
CHANGED
@@ -3,33 +3,32 @@ require 'rake'
|
|
3
3
|
require 'rake/gempackagetask'
|
4
4
|
require 'fileutils'
|
5
5
|
include FileUtils
|
6
|
+
require 'tmpdir'
|
6
7
|
require 'rake/rdoctask'
|
7
8
|
require 'rake/testtask'
|
8
9
|
|
9
10
|
desc 'Default: run tests in the proper environment'
|
10
|
-
task :default =>
|
11
|
+
task :default => :test
|
11
12
|
|
12
13
|
def common_test_task(t)
|
13
14
|
t.libs << "lib"
|
14
|
-
t.test_files = FileList['test/*_test.rb', 'test/t*.rb']
|
15
|
+
t.test_files = FileList['test/*_test.rb', 'test/t[0-9]*.rb']
|
15
16
|
t.verbose = true
|
16
17
|
end
|
17
|
-
Rake::TestTask.new {|t| common_test_task t }
|
18
|
+
Rake::TestTask.new("bare:test") {|t| common_test_task t }
|
18
19
|
|
19
20
|
begin
|
20
21
|
require 'rcov/rcovtask'
|
21
|
-
Rcov::RcovTask.new {|t| common_test_task t }
|
22
|
+
Rcov::RcovTask.new("bare:rcov") {|t| common_test_task t }
|
22
23
|
rescue LoadError
|
23
24
|
# no rcov, never mind
|
24
25
|
end
|
25
26
|
|
26
27
|
%w(test rcov).each do |tname|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
system "./test_env rake #{tname}"
|
32
|
-
end
|
28
|
+
desc "Run bare:#{tname} in the proper environment"
|
29
|
+
task tname do |t|
|
30
|
+
cd "test" do
|
31
|
+
system "./test_env rake bare:#{tname}"
|
33
32
|
end
|
34
33
|
end
|
35
34
|
end
|
@@ -40,6 +39,17 @@ Rake::GemPackageTask.new(GEMSPEC) do |pkg|
|
|
40
39
|
# no other formats needed
|
41
40
|
end
|
42
41
|
|
42
|
+
desc "Build a package from a clone of the local Git repo"
|
43
|
+
task :package_git do |t|
|
44
|
+
Dir.mktmpdir do |temp|
|
45
|
+
sh "git clone . #{temp}"
|
46
|
+
cd temp do
|
47
|
+
sh "rake package"
|
48
|
+
end
|
49
|
+
cp_r "#{temp}/pkg", "."
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
43
53
|
Rake::RDocTask.new do |rd|
|
44
54
|
rd.rdoc_dir = 'doc/rdoc'
|
45
55
|
rd.rdoc_files.include("README", "lib/**/*.rb")
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.7.0
|
data/lib/dbus/auth.rb
CHANGED
@@ -8,6 +8,8 @@
|
|
8
8
|
|
9
9
|
$debug = $DEBUG #it's all over the state machine
|
10
10
|
|
11
|
+
require 'rbconfig'
|
12
|
+
|
11
13
|
module DBus
|
12
14
|
# Exception raised when authentication fails somehow.
|
13
15
|
class AuthenticationFailed < Exception
|
@@ -62,7 +64,7 @@ module DBus
|
|
62
64
|
# name of cookie file, id of cookie in file, servers random challenge
|
63
65
|
context, id, s_challenge = data.split(' ')
|
64
66
|
# Random client challenge
|
65
|
-
c_challenge = Array.new(s_challenge.
|
67
|
+
c_challenge = Array.new(s_challenge.bytesize/2).map{|obj|obj=rand(255).to_s}.join
|
66
68
|
# Search cookie file for id
|
67
69
|
path = File.join(ENV['HOME'], '.dbus-keyrings', context)
|
68
70
|
puts "DEBUG: path: #{path.inspect}" if $debug
|
@@ -118,7 +120,11 @@ module DBus
|
|
118
120
|
|
119
121
|
# Start the authentication process.
|
120
122
|
def authenticate
|
121
|
-
|
123
|
+
if (RbConfig::CONFIG["target_os"] =~ /bsd/)
|
124
|
+
@socket.sendmsg(0.chr, 0, nil, [:SOCKET, :SCM_CREDS, ""])
|
125
|
+
else
|
126
|
+
@socket.write(0.chr)
|
127
|
+
end
|
122
128
|
next_authenticator
|
123
129
|
@state = :Starting
|
124
130
|
while @state != :Authenticated
|
@@ -142,12 +148,12 @@ module DBus
|
|
142
148
|
# Try authentication using the next authenticator.
|
143
149
|
def next_authenticator
|
144
150
|
begin
|
145
|
-
raise
|
151
|
+
raise AuthenticationFailed if @auth_list.size == 0
|
146
152
|
@authenticator = @auth_list.shift.new
|
147
153
|
auth_msg = ["AUTH", @authenticator.name, @authenticator.authenticate]
|
148
154
|
puts "DEBUG: auth_msg: #{auth_msg.inspect}" if $debug
|
149
155
|
send(auth_msg)
|
150
|
-
rescue
|
156
|
+
rescue AuthenticationFailed
|
151
157
|
@socket.close
|
152
158
|
raise
|
153
159
|
end
|
@@ -161,7 +167,7 @@ module DBus
|
|
161
167
|
while left > 0
|
162
168
|
buf = @socket.read( left > 1 ? 1 : left )
|
163
169
|
break if buf.nil?
|
164
|
-
left -= buf.
|
170
|
+
left -= buf.bytesize
|
165
171
|
data += buf
|
166
172
|
break if data.include? crlf #crlf means line finished, the TCP socket keeps on listening, so we break
|
167
173
|
end
|
data/lib/dbus/bus.rb
CHANGED
@@ -140,6 +140,7 @@ module DBus
|
|
140
140
|
end
|
141
141
|
|
142
142
|
# Return an XML string representation of the node.
|
143
|
+
# It is shallow, not recursing into subnodes
|
143
144
|
def to_xml
|
144
145
|
xml = '<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
|
145
146
|
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
@@ -383,33 +384,52 @@ module DBus
|
|
383
384
|
'
|
384
385
|
# This apostroph is for syntax highlighting editors confused by above xml: "
|
385
386
|
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
send_sync(
|
387
|
+
# Send a _message_.
|
388
|
+
# If _reply_handler_ is not given, wait for the reply
|
389
|
+
# and return the reply, or raise the error.
|
390
|
+
# If _reply_handler_ is given, it will be called when the reply
|
391
|
+
# eventually arrives, with the reply message as the 1st param
|
392
|
+
# and its params following
|
393
|
+
def send_sync_or_async(message, &reply_handler)
|
394
|
+
ret = nil
|
395
|
+
if reply_handler.nil?
|
396
|
+
send_sync(message) do |rmsg|
|
396
397
|
if rmsg.is_a?(Error)
|
397
398
|
raise rmsg
|
398
399
|
else
|
399
|
-
|
400
|
+
ret = rmsg.params
|
400
401
|
end
|
401
402
|
end
|
402
403
|
else
|
403
|
-
|
404
|
-
on_return(m) do |rmsg|
|
404
|
+
on_return(message) do |rmsg|
|
405
405
|
if rmsg.is_a?(Error)
|
406
|
-
|
406
|
+
reply_handler.call(rmsg)
|
407
407
|
else
|
408
|
-
|
408
|
+
reply_handler.call(rmsg, * rmsg.params)
|
409
409
|
end
|
410
410
|
end
|
411
|
+
send(message.marshall)
|
412
|
+
end
|
413
|
+
ret
|
414
|
+
end
|
415
|
+
|
416
|
+
def introspect_data(dest, path, &reply_handler)
|
417
|
+
m = DBus::Message.new(DBus::Message::METHOD_CALL)
|
418
|
+
m.path = path
|
419
|
+
m.interface = "org.freedesktop.DBus.Introspectable"
|
420
|
+
m.destination = dest
|
421
|
+
m.member = "Introspect"
|
422
|
+
m.sender = unique_name
|
423
|
+
if reply_handler.nil?
|
424
|
+
send_sync_or_async(m).first
|
425
|
+
else
|
426
|
+
send_sync_or_async(m) do |*args|
|
427
|
+
# TODO test async introspection, is it used at all?
|
428
|
+
args.shift # forget the message, pass only the text
|
429
|
+
reply_handler.call(*args)
|
430
|
+
nil
|
431
|
+
end
|
411
432
|
end
|
412
|
-
nil
|
413
433
|
end
|
414
434
|
|
415
435
|
# Issues a call to the org.freedesktop.DBus.Introspectable.Introspect method
|
@@ -549,9 +569,7 @@ module DBus
|
|
549
569
|
return if retm.nil? #check if somethings wrong
|
550
570
|
|
551
571
|
process(retm)
|
552
|
-
|
553
|
-
DBus::Message::METHOD_RETURN].include?(retm.message_type) and
|
554
|
-
retm.reply_serial == m.serial
|
572
|
+
while @method_call_replies.has_key? m.serial
|
555
573
|
retm = wait_for_message
|
556
574
|
process(retm)
|
557
575
|
end
|
@@ -695,10 +713,10 @@ module DBus
|
|
695
713
|
# = D-Bus session bus class
|
696
714
|
#
|
697
715
|
# The session bus is a session specific bus (mostly for desktop use).
|
698
|
-
#
|
699
|
-
|
700
|
-
|
701
|
-
|
716
|
+
#
|
717
|
+
# Use SessionBus, the non-singleton ASessionBus is
|
718
|
+
# for the test suite.
|
719
|
+
class ASessionBus < Connection
|
702
720
|
# Get the the default session bus.
|
703
721
|
def initialize
|
704
722
|
super(ENV["DBUS_SESSION_BUS_ADDRESS"] || address_from_file)
|
@@ -719,13 +737,20 @@ module DBus
|
|
719
737
|
end
|
720
738
|
end
|
721
739
|
|
740
|
+
# See ASessionBus
|
741
|
+
class SessionBus < ASessionBus
|
742
|
+
include Singleton
|
743
|
+
end
|
744
|
+
|
745
|
+
|
722
746
|
# = D-Bus system bus class
|
723
747
|
#
|
724
748
|
# The system bus is a system-wide bus mostly used for global or
|
725
|
-
# system usages.
|
726
|
-
|
727
|
-
|
728
|
-
|
749
|
+
# system usages.
|
750
|
+
#
|
751
|
+
# Use SystemBus, the non-singleton ASystemBus is
|
752
|
+
# for the test suite.
|
753
|
+
class ASystemBus < Connection
|
729
754
|
# Get the default system bus.
|
730
755
|
def initialize
|
731
756
|
super(SystemSocketName)
|
@@ -755,6 +780,11 @@ module DBus
|
|
755
780
|
end
|
756
781
|
end
|
757
782
|
|
783
|
+
# See ASystemBus
|
784
|
+
class SystemBus < ASystemBus
|
785
|
+
include Singleton
|
786
|
+
end
|
787
|
+
|
758
788
|
# Shortcut for the SystemBus instance
|
759
789
|
def DBus.system_bus
|
760
790
|
SystemBus.instance
|
data/lib/dbus/export.rb
CHANGED
@@ -15,19 +15,20 @@ module DBus
|
|
15
15
|
# = Exportable D-Bus object class
|
16
16
|
#
|
17
17
|
# Objects that are going to be exported by a D-Bus service
|
18
|
-
# should inherit from this class.
|
18
|
+
# should inherit from this class. At the client side, use ProxyObject.
|
19
19
|
class Object
|
20
20
|
# The path of the object.
|
21
21
|
attr_reader :path
|
22
|
-
# The interfaces that the object supports.
|
22
|
+
# The interfaces that the object supports. Hash: String => Interface
|
23
23
|
class_attribute :intfs
|
24
24
|
# The service that the object is exported by.
|
25
25
|
attr_writer :service
|
26
26
|
|
27
|
-
@@cur_intf = nil
|
27
|
+
@@cur_intf = nil # Interface
|
28
28
|
@@intfs_mutex = Mutex.new
|
29
29
|
|
30
30
|
# Create a new object with a given _path_.
|
31
|
+
# Use Service#export to export it.
|
31
32
|
def initialize(path)
|
32
33
|
@path = path
|
33
34
|
@service = nil
|
@@ -39,7 +40,7 @@ module DBus
|
|
39
40
|
self.intfs = (self.intfs || {}).merge({intf.name => intf})
|
40
41
|
end
|
41
42
|
|
42
|
-
# Dispatch a message _msg_
|
43
|
+
# Dispatch a message _msg_ to call exported methods
|
43
44
|
def dispatch(msg)
|
44
45
|
case msg.message_type
|
45
46
|
when Message::METHOD_CALL
|
@@ -73,8 +74,10 @@ module DBus
|
|
73
74
|
# belong to.
|
74
75
|
def self.dbus_interface(s)
|
75
76
|
@@intfs_mutex.synchronize do
|
76
|
-
@@cur_intf =
|
77
|
-
|
77
|
+
unless @@cur_intf = (self.intfs && self.intfs[s])
|
78
|
+
@@cur_intf = Interface.new(s)
|
79
|
+
self.intfs = (self.intfs || {}).merge({s => @@cur_intf})
|
80
|
+
end
|
78
81
|
yield
|
79
82
|
@@cur_intf = nil
|
80
83
|
end
|
data/lib/dbus/introspect.rb
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
# License, version 2.1 as published by the Free Software Foundation.
|
9
9
|
# See the file "COPYING" for the exact licensing terms.
|
10
10
|
|
11
|
+
# TODO check if it is slow, make replaceable
|
11
12
|
require 'rexml/document'
|
12
13
|
|
13
14
|
module DBus
|
@@ -27,15 +28,16 @@ module DBus
|
|
27
28
|
# = D-Bus interface class
|
28
29
|
#
|
29
30
|
# This class is the interface descriptor. In most cases, the Introspect()
|
30
|
-
# method call
|
31
|
+
# method call instantiates and configures this class for us.
|
31
32
|
#
|
32
33
|
# It also is the local definition of interface exported by the program.
|
34
|
+
# At the client side, see ProxyObjectInterface
|
33
35
|
class Interface
|
34
|
-
# The name of the interface.
|
36
|
+
# The name of the interface. String
|
35
37
|
attr_reader :name
|
36
|
-
# The methods that are part of the interface.
|
38
|
+
# The methods that are part of the interface. Hash: Symbol => DBus::Method
|
37
39
|
attr_reader :methods
|
38
|
-
# The signals that are part of the interface.
|
40
|
+
# The signals that are part of the interface. Hash: Symbol => Signal
|
39
41
|
attr_reader :signals
|
40
42
|
|
41
43
|
# Creates a new interface with a given _name_.
|
@@ -47,7 +49,7 @@ module DBus
|
|
47
49
|
|
48
50
|
# Validates a service _name_.
|
49
51
|
def validate_name(name)
|
50
|
-
raise InvalidIntrospectionData if name.
|
52
|
+
raise InvalidIntrospectionData if name.bytesize > 255
|
51
53
|
raise InvalidIntrospectionData if name =~ /^\./ or name =~ /\.$/
|
52
54
|
raise InvalidIntrospectionData if name =~ /\.\./
|
53
55
|
raise InvalidIntrospectionData if not name =~ /\./
|
@@ -100,14 +102,14 @@ module DBus
|
|
100
102
|
# This is a generic class for entities that are part of the interface
|
101
103
|
# such as methods and signals.
|
102
104
|
class InterfaceElement
|
103
|
-
# The name of the interface element.
|
105
|
+
# The name of the interface element. Symbol
|
104
106
|
attr_reader :name
|
105
|
-
# The parameters of the interface element
|
107
|
+
# The parameters of the interface element. Array: FormalParameter
|
106
108
|
attr_reader :params
|
107
109
|
|
108
110
|
# Validates element _name_.
|
109
111
|
def validate_name(name)
|
110
|
-
if (not name =~ MethodSignalRE) or (name.
|
112
|
+
if (not name =~ MethodSignalRE) or (name.bytesize > 255)
|
111
113
|
raise InvalidMethodName, name
|
112
114
|
end
|
113
115
|
end
|
@@ -135,7 +137,7 @@ module DBus
|
|
135
137
|
#
|
136
138
|
# This is a class representing methods that are part of an interface.
|
137
139
|
class Method < InterfaceElement
|
138
|
-
# The list of return values for the method.
|
140
|
+
# The list of return values for the method. Array: FormalParameter
|
139
141
|
attr_reader :rets
|
140
142
|
|
141
143
|
# Creates a new method interface element with the given _name_.
|
@@ -227,10 +229,9 @@ module DBus
|
|
227
229
|
@xml = xml
|
228
230
|
end
|
229
231
|
|
230
|
-
#
|
232
|
+
# return the names of direct subnodes
|
231
233
|
def parse_subnodes
|
232
234
|
subnodes = Array.new
|
233
|
-
t = Time.now
|
234
235
|
d = REXML::Document.new(@xml)
|
235
236
|
d.elements.each("node/node") do |e|
|
236
237
|
subnodes << e.attributes["name"]
|
@@ -238,9 +239,9 @@ module DBus
|
|
238
239
|
subnodes
|
239
240
|
end
|
240
241
|
|
241
|
-
#
|
242
|
+
# return a pair: [list of Interfaces, list of direct subnode names]
|
242
243
|
def parse
|
243
|
-
|
244
|
+
interfaces = Array.new
|
244
245
|
subnodes = Array.new
|
245
246
|
t = Time.now
|
246
247
|
d = REXML::Document.new(@xml)
|
@@ -259,13 +260,13 @@ module DBus
|
|
259
260
|
parse_methsig(se, s)
|
260
261
|
i << s
|
261
262
|
end
|
262
|
-
|
263
|
+
interfaces << i
|
263
264
|
end
|
264
265
|
d = Time.now - t
|
265
266
|
if d > 2
|
266
267
|
puts "Some XML took more that two secs to parse. Optimize me!" if $DEBUG
|
267
268
|
end
|
268
|
-
[
|
269
|
+
[interfaces, subnodes]
|
269
270
|
end
|
270
271
|
|
271
272
|
######################################################################
|
@@ -342,7 +343,7 @@ module DBus
|
|
342
343
|
methdef = "def #{m.name}("
|
343
344
|
methdef += (0..(m.params.size - 1)).to_a.collect { |n|
|
344
345
|
"arg#{n}"
|
345
|
-
}.join(", ")
|
346
|
+
}.push("&reply_handler").join(", ")
|
346
347
|
methdef += %{)
|
347
348
|
msg = Message.new(Message::METHOD_CALL)
|
348
349
|
msg.path = @object.path
|
@@ -365,26 +366,7 @@ module DBus
|
|
365
366
|
idx += 1
|
366
367
|
end
|
367
368
|
methdef += "
|
368
|
-
|
369
|
-
if block_given?
|
370
|
-
@object.bus.on_return(msg) do |rmsg|
|
371
|
-
if rmsg.is_a?(Error)
|
372
|
-
yield(rmsg)
|
373
|
-
else
|
374
|
-
yield(rmsg, *rmsg.params)
|
375
|
-
end
|
376
|
-
end
|
377
|
-
@object.bus.send(msg.marshall)
|
378
|
-
else
|
379
|
-
@object.bus.send_sync(msg) do |rmsg|
|
380
|
-
if rmsg.is_a?(Error)
|
381
|
-
raise rmsg
|
382
|
-
else
|
383
|
-
ret = rmsg.params
|
384
|
-
end
|
385
|
-
end
|
386
|
-
end
|
387
|
-
ret
|
369
|
+
@object.bus.send_sync_or_async(msg, &reply_handler)
|
388
370
|
end
|
389
371
|
"
|
390
372
|
singleton_class.class_eval(methdef)
|
@@ -448,7 +430,7 @@ module DBus
|
|
448
430
|
# over the bus so that the method is executed remotely on the correctponding
|
449
431
|
# object.
|
450
432
|
class ProxyObject
|
451
|
-
# The subnodes of the object in the tree.
|
433
|
+
# The names of direct subnodes of the object in the tree.
|
452
434
|
attr_accessor :subnodes
|
453
435
|
# Flag determining whether the object has been introspected.
|
454
436
|
attr_accessor :introspected
|
@@ -458,7 +440,7 @@ module DBus
|
|
458
440
|
attr_reader :path
|
459
441
|
# The bus the object is reachable via.
|
460
442
|
attr_reader :bus
|
461
|
-
# The default interface of the object.
|
443
|
+
# The default interface of the object, as String.
|
462
444
|
attr_accessor :default_iface
|
463
445
|
|
464
446
|
# Creates a new proxy object living on the given _bus_ at destination _dest_
|
@@ -495,11 +477,12 @@ module DBus
|
|
495
477
|
|
496
478
|
# Returns whether the object has an interface with the given _name_.
|
497
479
|
def has_iface?(name)
|
498
|
-
raise "Cannot call has_iface?
|
480
|
+
raise "Cannot call has_iface? if not introspected" if not @introspected
|
499
481
|
@interfaces.member?(name)
|
500
482
|
end
|
501
483
|
|
502
484
|
# Registers a handler, the code block, for a signal with the given _name_.
|
485
|
+
# It uses _default_iface_ which must have been set.
|
503
486
|
def on_signal(name, &block)
|
504
487
|
if @default_iface and has_iface?(@default_iface)
|
505
488
|
@interfaces[@default_iface].on_signal(@bus, name, &block)
|
@@ -521,10 +504,9 @@ module DBus
|
|
521
504
|
rescue NameError => e
|
522
505
|
# interesting, foo.method("unknown")
|
523
506
|
# raises NameError, not NoMethodError
|
524
|
-
|
525
|
-
raise unless match and match[2] == "DBus::ProxyObjectInterface"
|
507
|
+
raise unless e.to_s =~ /undefined method `#{name}'/
|
526
508
|
# BTW e.exception("...") would preserve the class.
|
527
|
-
raise NoMethodError,"undefined method `#{
|
509
|
+
raise NoMethodError,"undefined method `#{name}' for DBus interface `#{@default_iface}' on object `#{@path}'"
|
528
510
|
end
|
529
511
|
else
|
530
512
|
# TODO distinguish:
|