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

Re: [Vala] what does # mean in a member method formal parameter?



Yu Feng <rainwoodman gmail com> writes:

> what does # mean in a member method formal parameter?
> Generally, # stands for ownership transfer; But there are some
> in-consistence. Consider the following two examples:
>
>
> 1. if I write a library by vala:
>
> class MyHashTable: Object{
>   void insert(Object # obj) {
>     ..
>   }
>   static void test {
>      MyHashTable h;
>      Object o;
>      h.insert(o = new Object());
>   }
> }
> I will get 
> MyHashTable_test(){
>    MyHashTable_insert(g_object_ref(tmp));
> }
> and 
> MyHashTable_insert(GObject *o ){
>    ....
>    ....
>    g_object_unref(o);
> }
>
> what happens is during the life time of insert the ownership of 'o' is
> guarantted to be held in 'h'; then the reference is removed. The total
> effect is the ownership is not transferred to 'h' at all; 
>

1. Use generics
2. Why not reuse the code and use libgee?
3. If you put the object somewhere it also be refed.

void insert(Object #o) {
     obj = o;
}

will generate:
GObject* _tmp1;
GObject* _tmp0;
g_return_if_fail (self != NULL);
g_return_if_fail (o == NULL || G_IS_OBJECT (o));
_tmp1 = NULL;
_tmp0 = NULL;
self->obj = (_tmp1 = (_tmp0 = o, (_tmp0 == NULL ? NULL : g_object_ref (_tmp0))), (self->obj == NULL ? NULL : (self->obj = (g_object_unref (self->obj), NULL))), _tmp1);
(o == NULL ? NULL : (o = (g_object_unref (o), NULL)));

and
void insert(Object #o) {
     obj = #o;
}

will generate:
GObject* _tmp1;
GObject* _tmp0;
g_return_if_fail (self != NULL);
g_return_if_fail (o == NULL || G_IS_OBJECT (o));
_tmp1 = NULL;
_tmp0 = NULL;
self->obj = (_tmp1 = (_tmp0 = o, o = NULL, _tmp0), (self->obj == NULL ? NULL : (self->obj = (g_object_unref (self->obj), NULL))), _tmp1);
(o == NULL ? NULL : (o = (g_object_unref (o), NULL)));

(as o == NULL after the assigment the last g_object_unref will never be called).

> 2. Now consider the same .vapi, but a route in GLib:
> GHashTable.insert(#key, #obj);
>

Do you mean GLib.HashTable? What version of vala are you using?

> GHashTable h = new GHashTable.full(....,....,g_free, g_object_unref);
> h.insert("key", o = new Object());
>

IMHO better (motr type-safe):
GLib.HashTable<String, Object> h = new HashTable<String, Object>(...);

> the code will be 
> g_hash_table_insert(g_strdup(key)), g_object_ref(o));
>
> and 'h' will own 'o' until one removes o from the hash table.
>
>
> The two behaviors are inconsistent. 
>

They are consistent IMHO. They return something, which may be freed
by hashtable.

> I propose to (1) remove the tailing unref code when there is a ownership
> transfer tag in the declaration;

You may do something like that by:
h.insert("key2", #o);

o will become null to avoid problems with destruction of hash before time:
h.insert("key2", #o);
h = null; // Will call unref and probably destoy table and hence unref all hold
// objects.
o.something(); //Oops. It's destroyed...

> or (2) to completely ignore the # tag,
> and relies on the programmer to explicitly claim a reference of 'o' by
> o.ref().
>

Well - the point of vala is to make things simpler. Managing references is one
way of doing it.

> Yu

Regards
-- 
I've probably left my head... somewhere. Please wait untill I find it.
Homepage (pl_PL): http://uzytkownik.jogger.pl/
(GNU/)Linux User: #425935 (see http://counter.li.org/)



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