class DBus::ProxyObject
D-Bus proxy object class
Class
representing a remote object in an external application. Typically, calling a method on an instance of a ProxyObject
sends a message over the bus so that the method is executed remotely on the correctponding object.
Attributes
@api private @return [ApiOptions]
The bus the object is reachable via.
@return [String] The name of the default interface of the object.
The (remote) destination of the object.
Flag determining whether the object has been introspected.
The path to the object.
The names of direct subnodes of the object in the tree.
Public Class Methods
Creates a new proxy object living on the given bus at destination dest on the given path.
# File lib/dbus/proxy_object.rb 36 def initialize(bus, dest, path, api: ApiOptions::CURRENT) 37 @bus = bus 38 @destination = dest 39 @path = ObjectPath.new(path) 40 @introspected = false 41 @interfaces = {} 42 @subnodes = [] 43 @api = api 44 end
Public Instance Methods
Retrieves an interface of the proxy object @param [String] intfname @return [ProxyObjectInterface]
# File lib/dbus/proxy_object.rb 55 def [](intfname) 56 introspect unless introspected 57 ifc = @interfaces[intfname] 58 raise DBus::Error, "no such interface `#{intfname}' on object `#{@path}'" unless ifc 59 ifc 60 end
Maps the given interface name intfname to the given interface _intf. @param [String] intfname @param [ProxyObjectInterface] intf @return [ProxyObjectInterface] @api private
# File lib/dbus/proxy_object.rb 67 def []=(intfname, intf) 68 @interfaces[intfname] = intf 69 end
For each non duplicated method name in any interface present on the caller, defines a shortcut method dynamically. This function is automatically called when a {ProxyObject} is introspected.
# File lib/dbus/proxy_object.rb 85 def define_shortcut_methods 86 # builds a list of duplicated methods 87 dup_meths = [] 88 univocal_meths = {} 89 @interfaces.each_value do |intf| 90 intf.methods.each_value do |meth| 91 name = meth.name.to_sym 92 # don't overwrite instance methods! 93 next if dup_meths.include?(name) 94 next if self.class.instance_methods.include?(name) 95 if univocal_meths.include? name 96 univocal_meths.delete name 97 dup_meths << name 98 else 99 univocal_meths[name] = intf 100 end 101 end 102 end 103 univocal_meths.each do |name, intf| 104 # creates a shortcut function that forwards each call to the method on 105 # the appropriate intf 106 singleton_class.class_eval do 107 redefine_method name do |*args, &reply_handler| 108 intf.method(name).call(*args, &reply_handler) 109 end 110 end 111 end 112 end
Returns whether the object has an interface with the given name.
# File lib/dbus/proxy_object.rb 115 def has_iface?(name) 116 introspect unless introspected 117 @interfaces.key?(name) 118 end
Returns the interfaces of the object.
# File lib/dbus/proxy_object.rb 47 def interfaces 48 introspect unless introspected 49 @interfaces.keys 50 end
Introspects the remote object. Allows you to find and select interfaces on the object.
# File lib/dbus/proxy_object.rb 73 def introspect 74 # Synchronous call here. 75 xml = @bus.introspect_data(@destination, @path) 76 ProxyObjectFactory.introspect_into(self, xml) 77 define_shortcut_methods 78 xml 79 end
Registers a handler, the code block, for a signal with the given name. It uses default_iface which must have been set. @return [void]
# File lib/dbus/proxy_object.rb 123 def on_signal(name, &block) 124 # TODO: improve 125 raise NoMethodError unless @default_iface && has_iface?(@default_iface) 126 @interfaces[@default_iface].on_signal(name, &block) 127 end
Private Instance Methods
Handles all unkown methods, mostly to route method calls to the default interface.
# File lib/dbus/proxy_object.rb 134 def method_missing(name, *args, &reply_handler) 135 unless @default_iface && has_iface?(@default_iface) 136 # TODO: distinguish: 137 # - di not specified 138 # TODO 139 # - di is specified but not found in introspection data 140 raise NoMethodError, "undefined method `#{name}' for DBus interface `#{@default_iface}' on object `#{@path}'" 141 end 142 143 begin 144 @interfaces[@default_iface].method(name).call(*args, &reply_handler) 145 rescue NameError => e 146 # interesting, foo.method("unknown") 147 # raises NameError, not NoMethodError 148 raise unless e.to_s =~ /undefined method `#{name}'/ 149 # BTW e.exception("...") would preserve the class. 150 raise NoMethodError, "undefined method `#{name}' for DBus interface `#{@default_iface}' on object `#{@path}'" 151 end 152 end