Re: Behaviour of getters wrt dup/ref

2007-09-20 Thread Tim Janik
On Fri, 14 Sep 2007, Alexander Larsson wrote:

 I got some feedback on gio about a getter function that returned a ref,
 and now I'm reviewing the gio APIs for things like that, making sure its
 internally consistent and consistent with gtk+/glib.

 However, I'm not sure what the gtk+ standard for this is. I heard no
 reffing getters, but that is somewhat limited.

[without following the rest of this thread...]

we discussed this back in the day when we still could have changed matters
to be consistently across the platform. i believe the general getter/dup/peek
discussion should be in the gnome-hackers archive around 2000.
the short story is this:
- it was suggested to name getters 'peek' if they returned pointers to memoery
   that was not duplicated or referenced. i.e. not owned by the caller.
- it was suggested to name getters 'dup' (or 'ref') if they returned pointers
   to memoery that was allocated or referenced for the purpose of the getter,
   i.e. owned by the caller.
- after a lengthy discussion, both suggestions got rejected and we stuck with:
   a) a getter is usually named '_get_'
   b) memory returned by a getter can be duplicated/referenced or not, that
  depends on the getter. the user always has to refer to the documentation
  or source code here.
   c) for strings, getters that return memory not owned by the caller should
  use G_CONST_RETURN.


a good reason for why there is no simple convention for getters is the
case of getting a list of objects. in some cases you'd want to be able
to peek at the internally stored list nodes for performance reasons, e.g.:

/* returned list *not* owed by caller */
GSList* gtk_window_peek_toplevels (void);
free: /*noop*/

in others, you'd e.g. buy the overhead of a list copy for the sake of always
returning doubly linked lists and do:

/* returned list owed by caller, but not references */
GList* gtk_window_list_toplevels (void);
free: g_list_free (return_value);

and then again, for some object lists where it's common practice to modify or
destroy some of the returned instances, or where it's likely to have a
concurrent entity deleting/adding/shuffling items in the list, it may make
most sense to hand out extra object references:

/* returned list and additional references owed by caller */
GList* gtk_window_list_toplevels_refed (void);
free: g_list_foreach (return_value, g_object_unref, NULL);
  g_list_free (return_value);

---
ciaoTJ
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Behaviour of getters wrt dup/ref

2007-09-20 Thread Alexander Larsson
On Thu, 2007-09-20 at 13:37 +0200, Tim Janik wrote:
 On Fri, 14 Sep 2007, Alexander Larsson wrote:
 
  I got some feedback on gio about a getter function that returned a ref,
  and now I'm reviewing the gio APIs for things like that, making sure its
  internally consistent and consistent with gtk+/glib.
 
  However, I'm not sure what the gtk+ standard for this is. I heard no
  reffing getters, but that is somewhat limited.
 
 [without following the rest of this thread...]
 
 we discussed this back in the day when we still could have changed matters
 to be consistently across the platform. i believe the general getter/dup/peek
 discussion should be in the gnome-hackers archive around 2000.
 the short story is this:
 - it was suggested to name getters 'peek' if they returned pointers to memoery
that was not duplicated or referenced. i.e. not owned by the caller.
 - it was suggested to name getters 'dup' (or 'ref') if they returned pointers
to memoery that was allocated or referenced for the purpose of the getter,
i.e. owned by the caller.
 - after a lengthy discussion, both suggestions got rejected and we stuck with:
a) a getter is usually named '_get_'
b) memory returned by a getter can be duplicated/referenced or not, that
   depends on the getter. the user always has to refer to the documentation
   or source code here.
c) for strings, getters that return memory not owned by the caller should
   use G_CONST_RETURN.
 

Makes sense to me. Thanks.

___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Behaviour of getters wrt dup/ref

2007-09-17 Thread Alexander Larsson
On Sat, 2007-09-15 at 23:08 -0400, Behdad Esfahbod wrote:
 On Fri, 2007-09-14 at 10:35 -0400, Alexander Larsson wrote:
  
  char *  g_data_input_stream_get_line (GDataInputStream *data_stream,
gsize *length,
GCancellable *cancellable,
GError   **error);
  
  This actually reads new data from the stream, so it has to dup. One
  could imagine a similar call that returns some form of object instead
  of a string. 
 
 Hi Alex,
 
 I think it's pretty common in glib and pango at least to return
 g_strdup'ed strings.  The no-ref-count rule is mostly for objects that
 have a literal ref/unref pair.

Ok, lets start from the general rule that strings are strdup:ed and
gobjects are not ref:ed. 

Here are some violations of that in the gio api, reasons why, and
possible changes:

GList *   g_app_info_get_all_for_type (const char  *content_type);
GAppInfo *g_app_info_get_default_for_type (const char  *content_type);

These obviously have to return a ref:ed value, because the content type
string doesn't own the result. 
Maybe I should use another name for these. For instance
g_app_info_query_all_fo_type and g_app_info_query_default_for_type.

char *   g_content_type_get_description   (const char   *type);
char *   g_content_type_get_mime_type (const char   *type);
GIcon *  g_content_type_get_icon  (const char   *type);

Same here.

char *g_data_input_stream_get_line(...)

Independent on the memory allocation properties of this it really should
be read_line().

GDrive * g_volume_get_drive  (GVolume  *volume);

This currently refs the result for historical reasons. This API is quite
similar to the gnome-vfs volume manager API. There is a singleton volume
monitor that keeps track of the volumes and drives availible on the
system, which can change at any time. So, if you get the drive for a
volume you get the current value, which might change later. In gnome-vfs
this API is used by gnome-vfs backends, which means the API have to be
threadsafe, and the only way to make it threadsafe is to ref in the
getter. In gio we could decide to make this API not threadsafe and have
non-reffing getters. Opinions on this?

const char *g_file_info_get_attribute_string (GFileInfo  *info,
  const char *attribute);
and helpers like:
const char *g_file_info_get_name (GFileInfo  *info);

For these calls it really makes no sense to dup the code. The GFileInfo
is the container for the data, and we're just peeking at the data. This
is somewhat similar to g_value_get_string() which also doesn't dup.

GFile * g_file_get_parent (GFile *file);
GFile * g_file_get_child (GFile *file,
  const char *name);

These create a new GFile object, and there just is no way to not ref the
return value. Should we use a different name for these, and if so what?
I don't have any good ideas. Maybe just g_file_parent() /
g_file_child()?

GFileInfo *g_file_get_info (GFile  *file,
   const char  *attributes,
   GFileGetInfoFlagsflags,
   GCancellable*cancellable,
   GError **error);

This is not really a getter, but an i/o operator (its stat/lstat).
However, read_info() seems a bit weird name for this. Can anyone think
of a better name?

 Other than that, for functions that return read data from the stream,
 some people may have reasons to want to avoid malloc/free'ing on each
 line.  One way to work around that is to have the function take a
 GString, so you can reuse the buffer from the previous line.  I know
 most people are not a big fan of that idea though.

Hmmm, there are lots of lowlevel functions that you can use if you want
to do fancy array growing and whatnot. get_line() (or better,
read_line()) is mainly a very easy to use helper function for reading a
full line of text. I don't think we want to make it more complicated, as
then the whole point of it is sort of moot.


___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Behaviour of getters wrt dup/ref

2007-09-17 Thread Alexander Larsson
On Mon, 2007-09-17 at 11:57 +0200, Alexander Larsson wrote:

 char *g_data_input_stream_get_line(...)
 
 Independent on the memory allocation properties of this it really should
 be read_line().
 
 GFileInfo *g_file_get_info (GFile  *file,
  const char  *attributes,
  GFileGetInfoFlagsflags,
  GCancellable*cancellable,
  GError **error);

After some discussion on irc I decided that we at least should fix these
two. So, i changed all the i/o get_XXX() calls in GDataInputStreams to
be read_XXX(), and g_file_get_info() and related calls to
g_file_query_info().


___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Behaviour of getters wrt dup/ref

2007-09-16 Thread Yeti
On Sat, Sep 15, 2007 at 11:08:38PM -0400, Behdad Esfahbod wrote:
 On Fri, 2007-09-14 at 10:35 -0400, Alexander Larsson wrote:
  
  char *  g_data_input_stream_get_line (GDataInputStream *data_stream,
gsize *length,
GCancellable *cancellable,
GError   **error);
  
  This actually reads new data from the stream, so it has to dup. One
  could imagine a similar call that returns some form of object instead
  of a string. 
 
 I think it's pretty common in glib and pango at least to return
 g_strdup'ed strings.  The no-ref-count rule is mostly for objects that
 have a literal ref/unref pair.
 
 Other than that, for functions that return read data from the stream,
 some people may have reasons to want to avoid malloc/free'ing on each
 line.  One way to work around that is to have the function take a
 GString, so you can reuse the buffer from the previous line.  I know
 most people are not a big fan of that idea though.

The right interface for this type of functions have been
already invented: that of glibc's getline.  It can allocate
new buffers, it can reuse existing buffers resizing them if
necessary -- and it can be even used with GStrings [if they
use the same memory allocator] although that's a bit dirty.

Yeti

--
http://gwyddion.net/
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Behaviour of getters wrt dup/ref

2007-09-16 Thread Behdad Esfahbod
On Sun, 2007-09-16 at 03:03 -0400, David Nečas (Yeti) wrote:
 On Sat, Sep 15, 2007 at 11:08:38PM -0400, Behdad Esfahbod wrote:
  On Fri, 2007-09-14 at 10:35 -0400, Alexander Larsson wrote:
   
   char *  g_data_input_stream_get_line (GDataInputStream *data_stream,
 gsize *length,
 GCancellable *cancellable,
 GError   **error);
   
   This actually reads new data from the stream, so it has to dup. One
   could imagine a similar call that returns some form of object instead
   of a string. 
  
  I think it's pretty common in glib and pango at least to return
  g_strdup'ed strings.  The no-ref-count rule is mostly for objects that
  have a literal ref/unref pair.
  
  Other than that, for functions that return read data from the stream,
  some people may have reasons to want to avoid malloc/free'ing on each
  line.  One way to work around that is to have the function take a
  GString, so you can reuse the buffer from the previous line.  I know
  most people are not a big fan of that idea though.
 
 The right interface for this type of functions have been
 already invented: that of glibc's getline.  It can allocate
 new buffers, it can reuse existing buffers resizing them if
 necessary -- and it can be even used with GStrings [if they
 use the same memory allocator] although that's a bit dirty.

Well, that's exactly what happens if you make the API take GString.

 Yeti

-- 
behdad
http://behdad.org/

Those who would give up Essential Liberty to purchase a little
 Temporary Safety, deserve neither Liberty nor Safety.
-- Benjamin Franklin, 1759



___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Behaviour of getters wrt dup/ref

2007-09-16 Thread Yeti
On Sun, Sep 16, 2007 at 12:12:11PM -0400, Behdad Esfahbod wrote:
  
  The right interface for this type of functions have been
  already invented: that of glibc's getline.  It can allocate
  new buffers, it can reuse existing buffers resizing them if
  necessary -- and it can be even used with GStrings [if they
  use the same memory allocator] although that's a bit dirty.
 
 Well, that's exactly what happens if you make the API take GString.

I reacted to the remark that many people do not like having
to pass a GString (perhaps understandably).  The `decomposed
GString' interface of getline() is then the next reasonable
candidate.

Yeti

--
http://gwyddion.net/
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Behaviour of getters wrt dup/ref

2007-09-16 Thread Mathias Hasselmann
Am Sonntag, den 16.09.2007, 12:12 -0400 schrieb Behdad Esfahbod:
 On Sun, 2007-09-16 at 03:03 -0400, David Nečas (Yeti) wrote:
  On Sat, Sep 15, 2007 at 11:08:38PM -0400, Behdad Esfahbod wrote:
   On Fri, 2007-09-14 at 10:35 -0400, Alexander Larsson wrote:

char *  g_data_input_stream_get_line (GDataInputStream *data_stream,
  gsize *length,
  GCancellable *cancellable,
  GError   **error);

This actually reads new data from the stream, so it has to dup. One
could imagine a similar call that returns some form of object instead
of a string. 
   
   I think it's pretty common in glib and pango at least to return
   g_strdup'ed strings.  The no-ref-count rule is mostly for objects that
   have a literal ref/unref pair.
   
   Other than that, for functions that return read data from the stream,
   some people may have reasons to want to avoid malloc/free'ing on each
   line.  One way to work around that is to have the function take a
   GString, so you can reuse the buffer from the previous line.  I know
   most people are not a big fan of that idea though.
  
  The right interface for this type of functions have been
  already invented: that of glibc's getline.  It can allocate
  new buffers, it can reuse existing buffers resizing them if
  necessary -- and it can be even used with GStrings [if they
  use the same memory allocator] although that's a bit dirty.
 
 Well, that's exactly what happens if you make the API take GString.

Don't know if you try to support GString APIs, but I do not understand
any GString bashing (expect maybe for the missing reference counting).
In my opinion GString is a very useful member of the GLib API - so it
also should be used in the public API of other libraries when it makes
sense. Reading lines is such a place. A pattern I found useful for
read_line like stuff is this:

   const gchar*
   maman_bar_read_line (MamanBar *self, GString *buffer)
   {
 g_size offset;

 g_return_val_if_fail (MAMAN_IS_BAR (self), NULL);

 if (NULL == buffer)
   {
 g_string_truncate (self-priv-buffer, 0);
 buffer = self-priv-buffer;
   }

 offset = buffer-len;
 manan_bar_real_read_line (self, buffer);
 return buffer-str + offset;
   }

Sidenote to Alex: g_data_input_stream_get_line and its friend really
should use read as verb, not get. The verb get usually indicates
you do not change the state of an object - expect maybe for buffering
expensive data.

Ciao,
Mathias
-- 
Mathias Hasselmann [EMAIL PROTECTED]
http://taschenorakel.de/


signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Behaviour of getters wrt dup/ref

2007-09-15 Thread Mathias Hasselmann
Hi Alex,

Strange that nobody replied yet, so let's start discussion by dropping
some random thoughts:

For convenience and performance I consider returning a weak reference
(const char*) the most reasonable choice for getters. If you want to
keep a reference to the value returned longer than it is guaranteed to
be valid, you still can call g_strdup on the caller side --- without
putting any memory management overhead on callers which just want to
have a short look on your properties.

Well, but you raised the question for properties which have to be
evaluated before returning them so for those properties I see two
possibilities:

1) rename the methods from maman_get_bar to maman_eval_bar 
   (or similiar)

2) handle them as lazy evaluated properties:

 const char* maman_get_expensive_info (Maman *self) 
 {
   if (NULL == self-priv-expensive_info)
 self-priv-expensive_info = eval_expensive_info ();

   return self-priv-expensive_info;
 }

Every time you know that property could become invalid you reset the
_expensive_info field and of course you have to reset that field in your
object's dispose method. IMHO this pattern is quite common in OOP and
gives most convenience without sacrifing performance. 

Well, and if you think its reasonable to transfer ownership for that
expensive field to the caller, you still can follow the pattern
introduced by GValue:

 char* maman_steal_expensive_info (Maman *self) 
 {
   char *result = maman_get_expensive_info (self);
   self-priv-expensive_info = NULL;
   return result;
 }

Hope those thoughts help.

Ciao,
Mathias
-- 
Mathias Hasselmann [EMAIL PROTECTED]
http://taschenorakel.de/


signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Behaviour of getters wrt dup/ref

2007-09-15 Thread Mathias Hasselmann
Hi Alex,

Strange that nobody replied yet, so let's start discussion by dropping
some random thoughts:

For convenience and performance I consider returning a weak reference
(const char*) the most reasonable choice for getters. If you want to
keep a reference to the value returned longer than it is guaranteed to
be valid, you still can call g_strdup on the caller side --- without
putting any memory management overhead on callers which just want to
have a short look on your properties.

Well, but you raised the question for properties which have to be
evaluated before returning them so for those properties I see two
possibilities:

1) rename the methods from maman_get_bar to maman_eval_bar 
   (or similiar)

2) handle them as lazy evaluated properties:

 const char* maman_get_expensive_info (Maman *self) 
 {
   if (NULL == self-priv-expensive_info)
 self-priv-expensive_info = eval_expensive_info ();

   return self-priv-expensive_info;
 }

Every time you know that property could become invalid you reset the
_expensive_info field and of course you have to reset that field in your
object's dispose method. IMHO this pattern is quite common in OOP and
gives most convenience without sacrifing performance. 

Well, and if you think its reasonable to transfer ownership for that
expensive field to the caller, you still can follow the pattern
introduced by GValue:

 char* maman_steal_expensive_info (Maman *self) 
 {
   char *result = maman_get_expensive_info (self);
   self-priv-expensive_info = NULL;
   return result;
 }

Hope those thoughts help.

Ciao,
Mathias
-- 
Mathias Hasselmann [EMAIL PROTECTED]
http://taschenorakel.de/


signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Behaviour of getters wrt dup/ref

2007-09-15 Thread Behdad Esfahbod
On Fri, 2007-09-14 at 10:35 -0400, Alexander Larsson wrote:
 
 char *  g_data_input_stream_get_line (GDataInputStream *data_stream,
   gsize *length,
   GCancellable *cancellable,
   GError   **error);
 
 This actually reads new data from the stream, so it has to dup. One
 could imagine a similar call that returns some form of object instead
 of a string. 

Hi Alex,

I think it's pretty common in glib and pango at least to return
g_strdup'ed strings.  The no-ref-count rule is mostly for objects that
have a literal ref/unref pair.

Other than that, for functions that return read data from the stream,
some people may have reasons to want to avoid malloc/free'ing on each
line.  One way to work around that is to have the function take a
GString, so you can reuse the buffer from the previous line.  I know
most people are not a big fan of that idea though.

-- 
behdad
http://behdad.org/

Those who would give up Essential Liberty to purchase a little
 Temporary Safety, deserve neither Liberty nor Safety.
-- Benjamin Franklin, 1759



___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list