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

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



-------- 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]