# 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[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.

path[R]

The path to the object.

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
    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

[](intfname) click to toggle source

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

[]=(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
    67 def []=(intfname, intf)
    68   @interfaces[intfname] = intf
    69 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
     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

has_iface?(name) click to toggle source

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

interfaces() click to toggle source

Returns the interfaces of the object.

       # File lib/dbus/proxy_object.rb
    47 def interfaces
    48   introspect unless introspected
    49   @interfaces.keys
    50 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
    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

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
    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

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
    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