[Vala] [Fwd: Re: what does # mean in a member method formal parameter?]
- From: Yu Feng <rainwoodman gmail com>
- To: vala-list gnome org
- Subject: [Vala] [Fwd: Re: what does # mean in a member method formal parameter?]
- Date: Fri, 09 May 2008 15:20:42 -0400
-------- Forwarded Message --------
From: Maciej Piechotka <uzytkownik2 gmail com>
To: Yu Feng <rainwoodman gmail com>
Subject: Re: [Vala] what does # mean in a member method formal
parameter?
Date: Fri, 9 May 2008 21:16:28 +0200
On Fri, May 9, 2008 at 5:52 PM, Yu Feng <rainwoodman gmail com> wrote:
On Fri, 2008-05-09 at 11:18 +0200, Maciej Piechotka wrote:
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
This is a piece of example and MyHashTable is a collection of a specific
object.
2. Why not reuse the code and use libgee?
Because I am writing a library that don't want to introduce any
dependency except DBus and GLib. In other words, I am writing C code
with the help of vala.
3. If you put the object somewhere it also be refed.
I have to explicitly transfer the ownership from the method code block
to the object anyway.
Eighter I don't understend what you mean or you don't have to.
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).
obj = o is kind of confusing. I prefer obj = #o, but it lacks a
detection for the NULLness of self->obj.
It do not lack. Fragment of line: self->obj == NULL ? NULL :
(self->obj = (g_object_unref (self->obj), NULL))
with a lot of #s, from the caller(invocation) to the callee(formal
parameter, to the code block in the function the ownership of the object
ransfers like:
1: the caller code block gives the ownership to the callee by a # in the
invocation.
2: the callee pass the ownership to the callee body code block;
3: the callee code block gives the ownership to an object property; or
hold an ownership explicitly by using the .ref() method.
There are three ownership transfers involved in it, thus three #s shall
be needed.
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?
0.3.1
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.
Yes, I thought about it last night in the dream. They ARE consistent.
There is still something not so perfect. I had a clear(well defined)
model for the ownership issue and the use of # sign in mind now. I'll
write it somewhere and perhaps vala can adapt it.
I'm not vala dev so I can't help.
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...
Still, if you take a look at the generated CCode, there is an
unnecessary un_ref at the end of the code block.
Well - not exactly. One ref/unref cycle is added to code generated by
vala. However we, humans, know it as we have meaning of code in mind.
However I cannot imagine how it could be autogenerated without looking
into called method (and even then I guess it is not possible).
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.
Thus it seems to be OK to ignore the # sharp sign in the code generator for the formal reference.
Currently If there is a #, the callee will ref the object, and the caller will unref it at the exit.
The total effect is almost the same as without a #. (except some rare case where the object is unrefed
during the callee.
I guess that # for objects are mainly for generics.
Regards
PS. Why haven't you replied to group?
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]