Re: [Vala] Interfaces - why do they must have prerequisites?



I am really sorry for flood, but it just came into my mind:

(CCing Jürg , as I think I've found a bug in the object system design)

On Sun, Dec 05, 2010 at 17:32:17 +0100, Aleksander Wabik wrote:
I'm having class Foo, that is _NOT_ inheriting Object, but it's still
a typed class, and it's implementing interface IFoo. This is (or used to
be) legal.

No, it is not and never was legal. Interfaces depend on runtime support
provided by GObject and therefore only classes derived from GLib.Object may
implement interfaces.


Hi,

I think I've found the difference that causes this bug to reproduce or
not. In my whole program where it's not reproductible, I have never
declared interface instance as a local object (IFoo sth in the
function body); I create objects of class Foo, and assign them to
references of type Foo.

The interface is used in functions: function take argument of
interface type IFoo. It works! But if I try to create a reference of
interface type IFoo, error occurs. The demonstration code:

//-------- test.vala --------
namespace Test
{
      public interface IFoo
      {
              public abstract bool run();
      }
      
      public class Foo : IFoo
      {
              public virtual bool run()
              {
                      return true;
              }
      }
      
      public static bool test(IFoo ifoo)
      {
              return ifoo.run();
      }
      
      public static void main()
      {
              //IFoo ifoo = new Foo();
              Foo ifoo = new Foo();
              test(ifoo);
              return;
      }
}
//------ end test.vala ------

This code will compile fine. But if I uncomment the commented line, and
comment the next one, it SHOULD compile fine too, but it fails with the
same error:

test.vala:23.3-23.6: error: missing class prerequisite for interface
`Test.IFoo', add GLib.Object to interface declaration if unsure 
      IFoo ifoo = new Foo(); 
      ^^^^

So... it is a bug, right?

best regards,
AW.

As classes not inheriting from Object have different ref and unref
functions (Foo will have foo_ref, and foo_unref, Bar will have bar_ref
and bar_unref), if an object is referenced by the reference of interface
type, there's no possibility to ref and unref this object unless
knowing what ref and unref functions to use! This may be the cause why
creating references of interface type fails, and passing interface type
references to functions do not fail (there's no ref then).

This is a serious flaw to the object system IMO. It means, that there's
*no way* of having two classes that do not have common ancestor but
implement the same interface. Possible ways to solve this problem:

- make ref and unref virtual functions - IMO it's bad, performance will
  suffer,
- store ref and unref functions pointers in the interface somehow - can
  it be achieved?? I guess it will be not possible, as interface can
  not have fields? - and call these for references of the interface
  type.
- have abstract ref and unref interface functions, that will have to be
  implemented by the class that's implementing interface, and will
  have to return proper ref and unref function pointers for that class.
  - the only solution that can work, possibly? Performance for
  references of class type will not suffer, but for the references of
  interface type will suffer greatly...
- force all references of interface type to be unowned? - stupid, I can
  define them unowned if I want, but if I don't want it, I'll accept the
  performance hit for ref and unref.

Comments on this?

best regards,
AW.

-- 
Mój klucz publiczny o identyfikatorze 1024D/E12C5A4C znajduje się na
serwerze hkp://keys.gnupg.net

My public key with signature 1024D/E12C5A4C is on the server
hkp://keys.gnupg.net

Attachment: signature.asc
Description: PGP signature



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]