Skip to content
This repository has been archived by the owner on Jan 6, 2022. It is now read-only.

Whether you can remove the restrict of exported method must be return an *dbus.Error #35

Open
snyh opened this issue Nov 3, 2013 · 5 comments

Comments

@snyh
Copy link

snyh commented Nov 3, 2013

snyh@5d561fa

I think this restrict is no need.
If some function may return error then return one and handleCall can detect this error to invoke conn.sendError.

If the method must return an dbus.Error then this method can't used by other place natural.

this restrict will cause auto exported struct need use dbus.Error and I think unless the use want more control then no need to know the low-level api

@guelfey
Copy link
Owner

guelfey commented Nov 3, 2013

This restriction is mainly there to distinguish between "normal" exported methods and methods that should be accesible via D-Bus, which is admittedly ugly, but neccessary for packages like prop. If we find a way to properly merge the subpackages into the main package while retaining flexibility for the package user, the restriction can be lifted (or at least changed to requiring an error like net/rpc does) as I doubt that it is required or useful outside of this package.

Another solution would be to find another way to mark methods to be (not) exported on the bus, but leave them exported in the language, though I can't think of a nice one right now.

@jessevdk
Copy link
Contributor

I think without changing much, there is a kind of natural way to specify the subset of methods to be exported, using interfaces. Something like this:

// A service to be exported
type ServiceInterface interface {
    Capabilities() []string
}

type Service struct {
}

func newService(c *dbus.Conn) *Service {
    s := new(Service)
    i := ServiceInterface(s)

    c.Export(&i, "/org/domain/Service", "org.domain.Service")    
    return s
}

The only issue seems to be that you need to pass a pointer to the interface value to be able to extract the interface information using reflect. I.e. you can't just pass i itself because the ServiceInterface type will simply be converted to the empty interface. Of course, the Export method needs to be able to take this kind of construct into account.

@guelfey
Copy link
Owner

guelfey commented Nov 12, 2013

Duh; using (Go) interfaces is an obvious solution to this. I think that I already considered something like this, but forgot about it somehow.

I don't understand why you think that you need to pass a pointer to the interface value, though. I created a small test just now, and exporting the interface value directly seems to be working fine.

@jessevdk
Copy link
Contributor

See for example: http://play.golang.org/p/DrbkwjUnOl

Unless I misunderstand how you would like to implement this. What happens there is that the interface is converted to an empty interface{} which now just holds the underlying struct type (and not the intended interface type). So the information about the interface is lost at this point. The only way I found to preserve this information is to pass a pointer to the interface value, in which case the type information is preserved.

@guelfey
Copy link
Owner

guelfey commented Nov 12, 2013

I see. I don't really want to make a special case in the code for this construct, so I'll think about how we can avoid this.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants