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.

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, line 38
def initialize(bus, dest, path, api: ApiOptions::CURRENT)
  @bus = bus
  @destination = dest
  @path = ObjectPath.new(path)
  @introspected = false
  @interfaces = {}
  @subnodes = []
  @api = api
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, line 58
def [](intfname)
  introspect unless introspected
  ifc = @interfaces[intfname]
  raise DBus::Error, "no such interface `#{intfname}' on object `#{@path}'" unless ifc

  ifc
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, line 71
def []=(intfname, intf)
  @interfaces[intfname] = intf
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, line 89
def define_shortcut_methods
  # builds a list of duplicated methods
  dup_meths = []
  univocal_meths = {}
  @interfaces.each_value do |intf|
    intf.methods.each_value do |meth|
      name = meth.name.to_sym
      # don't overwrite instance methods!
      next if dup_meths.include?(name)
      next if self.class.instance_methods.include?(name)

      if univocal_meths.include? name
        univocal_meths.delete name
        dup_meths << name
      else
        univocal_meths[name] = intf
      end
    end
  end
  univocal_meths.each do |name, intf|
    # creates a shortcut function that forwards each call to the method on
    # the appropriate intf
    singleton_class.class_eval do
      redefine_method name do |*args, &reply_handler|
        intf.method(name).call(*args, &reply_handler)
      end
    end
  end
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, line 120
def has_iface?(name)
  introspect unless introspected
  @interfaces.key?(name)
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, line 50
def interfaces
  introspect unless introspected
  @interfaces.keys
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, line 77
def introspect
  # Synchronous call here.
  xml = @bus.introspect_data(@destination, @path)
  ProxyObjectFactory.introspect_into(self, xml)
  define_shortcut_methods
  xml
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, line 128
def on_signal(name, &block)
  unless @default_iface && has_iface?(@default_iface)
    raise NoMethodError, "undefined signal `#{name}' for DBus interface `#{@default_iface}' on object `#{@path}'"
  end

  @interfaces[@default_iface].on_signal(name, &block)
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, line 148
def method_missing(name, *args, &reply_handler)
  unless @default_iface && has_iface?(@default_iface)
    # TODO: distinguish:
    # - di not specified
    # TODO
    # - di is specified but not found in introspection data
    raise NoMethodError, "undefined method `#{name}' for DBus interface `#{@default_iface}' on object `#{@path}'"
  end

  begin
    @interfaces[@default_iface].method(name).call(*args, &reply_handler)
  rescue NameError => e
    # interesting, foo.method("unknown")
    # raises NameError, not NoMethodError
    raise unless e.to_s =~ /undefined method `#{name}'/

    # BTW e.exception("...") would preserve the class.
    raise NoMethodError, "undefined method `#{name}' for DBus interface `#{@default_iface}' on object `#{@path}'"
  end
end
respond_to_missing?(name, _include_private = false) click to toggle source

rubocop:enable Lint/MissingSuper

Calls superclass method
# File lib/dbus/proxy_object.rb, line 170
def respond_to_missing?(name, _include_private = false)
  @default_iface &&
    has_iface?(@default_iface) &&
    @interfaces[@default_iface].methods.key?(name) or super
end