Ticket #36 (closed defect: fixed)

Opened 9 years ago

Last modified 8 years ago

ruby-dbus doesn't support 2 differents classes

Reported by: miaoufkirsh@… Owned by: martin.github@…
Priority: normal Milestone:
Component: library Version:
Keywords: Cc: flagospub@…, lsdark73@…


Hi, I create two different classes of dbus object. When I export an object of one of them, all interfaces and methods from the other class appear in the introspection of the exported object.

Here the script to reproduce this bug.

require 'dbus'

bus = DBus.session_bus
service = bus.request_service("org.ruby.service")

class Test < DBus::Object
  # Create an interface.
  dbus_interface "org.ruby.SampleInterface" do
    # Create a hello method in that interface.
    dbus_method :hello, "in name:s, in name2:s" do |name, name2|
      puts "hello(#{name}, #{name2})" 

class Test2 < DBus::Object
  # Create a second interface.
  dbus_interface "org.ruby.SampleInterface2" do
    # Create a second hello method in that interface.
    dbus_method :hello2, "in name:s, in name2:s" do |name, name2|
      puts "hello(#{name}, #{name2})" 

exported_obj = Test.new("/org/ruby/MyInstance")

main = DBus::Main.new
main << bus

Here the result of introspect for the exported object using d-feet :


However, wrong methods can't be called, since the object of the second class doesn't exist.

It seems that objects are exported with all interfaces and methods which have been defined before.

This bug has been also reproduced by two friend of mine, runing on Ubuntu 9.10 and 10.04. We use the Git version of ruby-dbus.

Change History

Changed 9 years ago by miaoufkirsh@…

Here the solution

diff --git a/lib/dbus/export.rb b/lib/dbus/export.rb
index b92ae67..40a046e 100644
--- a/lib/dbus/export.rb
+++ b/lib/dbus/export.rb
@@ -43,7 +43,7 @@ module DBus
     # Create a new object with a given _path_.
     def initialize(path)
       @path = path
-      @intfs = @@intfs.dup
+      @intfs = @@intfs[self.class.to_s].dup
       @service = nil
@@ -83,7 +83,8 @@ module DBus
     # belong to.
     def self.dbus_interface(s)
       @@intfs_mutex.synchronize do
-        @@cur_intf = @@intfs[s] = Interface.new(s)
+		@@intfs[self.name] = Hash.new
+        @@cur_intf = @@intfs[self.name][s] = Interface.new(s)
         @@cur_intf = nil

Changed 9 years ago by miaoufkirsh@…

Sorry, I have made a small error : the new patch

+		if 	@@intfs[self.name]==nil 
+			@@intfs[self.name] = Hash.new
+		end


+		@@intfs[self.name] = Hash.new

Changed 9 years ago by martin.github@…

  • owner changed from nobody to martin.github@…

Thanks for the patch. I think we also need to consider subclasses, like DBus::Object < Base < Derived. The buggy implementation fakes the inheritance, and the patch would remove that.

Changed 9 years ago by miaoufkirsh@…

Thanks, I didn't thinks about subclasses.

at object's initialization, check the inheritance and merge interfaces

+      @@intfs.each_key { |key|
+			if self.kind_of? Class.class_eval(key)
+				if not @intfs
+					@intfs = @@intfs[key].dup
+				else
+					@intfs.merge!(@@intfs[key].dup)
+				end
+			end
+	  }

works with multiple levels of inheritance

I can't give the full patch in git format, the bug tracker thinks it's a spam ...

Changed 8 years ago by martin.github@…

  • status changed from new to closed
  • resolution set to fixed

I have solved it differently, by rewriting intfs to be a class_attribute (an extension from Rails)  http://github.com/mvidner/ruby-dbus/commit/986be02f1720dea5076bbec270bbe136ddbf1618

A new release will be out soon.

(Thanks to  http://github.com/mvidner/ruby-dbus/issues/#issue/5 for pinging me)

Note: See TracTickets for help on using tickets.