class DBus::ProxyObject
Represents 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 corresponding object.
Constants
- OPEN_QUOTE
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. @return [Boolean]
The path to the object. @return [ObjectPath]
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 40 def initialize(bus, dest, path, api: ApiOptions::CURRENT) 41 @bus = bus 42 @destination = dest 43 @path = ObjectPath.new(path) 44 @introspected = false 45 @interfaces = {} 46 @subnodes = [] 47 @api = api 48 end
Public Instance Methods
Retrieves an interface of the proxy object @param [String] intfname @return [ProxyObjectInterface]
# File lib/dbus/proxy_object.rb 60 def [](intfname) 61 introspect unless introspected 62 ifc = @interfaces[intfname] 63 raise DBus::Error, "no such interface #{OPEN_QUOTE}#{intfname}' on object #{OPEN_QUOTE}#{@path}'" unless ifc 64 65 ifc 66 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 73 def []=(intfname, intf) 74 @interfaces[intfname] = intf 75 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 91 def define_shortcut_methods 92 # builds a list of duplicated methods 93 dup_meths = [] 94 univocal_meths = {} 95 @interfaces.each_value do |intf| 96 intf.methods.each_value do |meth| 97 name = meth.name.to_sym 98 # don't overwrite instance methods! 99 next if dup_meths.include?(name) 100 next if self.class.instance_methods.include?(name) 101 102 if univocal_meths.include? name 103 univocal_meths.delete name 104 dup_meths << name 105 else 106 univocal_meths[name] = intf 107 end 108 end 109 end 110 univocal_meths.each do |name, intf| 111 # creates a shortcut function that forwards each call to the method on 112 # the appropriate intf 113 singleton_class.class_eval do 114 redefine_method name do |*args, &reply_handler| 115 intf.method(name).call(*args, &reply_handler) 116 end 117 end 118 end 119 end
Returns whether the object has an interface with the given name.
# File lib/dbus/proxy_object.rb 122 def has_iface?(name) 123 introspect unless introspected 124 @interfaces.key?(name) 125 end
Returns the interfaces of the object. @return [Array<String>] names of the interfaces
# File lib/dbus/proxy_object.rb 52 def interfaces 53 introspect unless introspected 54 @interfaces.keys 55 end
Introspects the remote object. Allows you to find and select interfaces on the object.
# File lib/dbus/proxy_object.rb 79 def introspect 80 # Synchronous call here. 81 xml = @bus.introspect_data(@destination, @path) 82 ProxyObjectFactory.introspect_into(self, xml) 83 define_shortcut_methods 84 xml 85 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 130 def on_signal(name, &block) 131 unless @default_iface && has_iface?(@default_iface) 132 raise NoMethodError, "undefined signal #{OPEN_QUOTE}#{name}' for DBus interface " \ 133 "#{OPEN_QUOTE}#{@default_iface}' on object #{OPEN_QUOTE}#{@path}'" 134 end 135 136 @interfaces[@default_iface].on_signal(name, &block) 137 end
Private Instance Methods
Handles all unkown methods, mostly to route method calls to the default interface.
# File lib/dbus/proxy_object.rb 144 def method_missing(name, *args, &reply_handler) 145 unless @default_iface && has_iface?(@default_iface) 146 # TODO: distinguish: 147 # - di not specified 148 # TODO 149 # - di is specified but not found in introspection data 150 raise NoMethodError, "undefined method #{OPEN_QUOTE}#{name}' for DBus interface " \ 151 "#{OPEN_QUOTE}#{@default_iface}' on object #{OPEN_QUOTE}#{@path}'" 152 end 153 154 begin 155 @interfaces[@default_iface].method(name).call(*args, &reply_handler) 156 rescue NameError => e 157 # interesting, foo.method("unknown") 158 # raises NameError, not NoMethodError 159 raise unless e.to_s =~ /undefined method #{OPEN_QUOTE}#{name}'/ 160 161 # BTW e.exception("...") would preserve the class. 162 raise NoMethodError, "undefined method #{OPEN_QUOTE}#{name}' for DBus interface " \ 163 "#{OPEN_QUOTE}#{@default_iface}' on object #{OPEN_QUOTE}#{@path}'" 164 end 165 end
# File lib/dbus/proxy_object.rb 167 def respond_to_missing?(name, _include_private = false) 168 (@default_iface && 169 has_iface?(@default_iface) && 170 @interfaces[@default_iface].methods.key?(name)) or super 171 end