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[R]

@api private @return [ApiOptions]

bus[R]

The bus the object is reachable via.

default_iface[RW]

@return [String] The name of the default interface of the object.

destination[R]

The (remote) destination of the object.

introspected[RW]

Flag determining whether the object has been introspected. @return [Boolean]

path[R]

The path to the object. @return [ObjectPath]

subnodes[RW]

The names of direct subnodes of the object in the tree.

Public Class Methods

new(bus, dest, path, api: ApiOptions::CURRENT) click to toggle source

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

[](intfname) click to toggle source

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
[]=(intfname, intf) click to toggle source

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
define_shortcut_methods() click to toggle source

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
has_iface?(name) click to toggle source

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
interfaces() click to toggle source

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
introspect() click to toggle source

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
on_signal(name, &block) click to toggle source

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

method_missing(name, *args, &reply_handler) click to toggle source

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
respond_to_missing?(name, _include_private = false) click to toggle source
Calls superclass method
    # 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