gtk2-perl: moving on by standardizing our code



Hi,

There are currently 8 developers with commit-rights on the
gtk2-perl project. I've noticed that the code style problem is
threatening us more and more. I'd like all people that do commit
in the project follow the same code style rules, for evident
maintainance problems.

I don't want to impose my own coding style, and actually I
usually use a 8-char tabstop when writing C code, that's why you
can notice at the end of the C sources some Emacs directives so
that I respect the 4-char tabstop initially chosen by Goran,
overriding my normal Emacs configuration. I'd like to write down
a few rules pointing problems I've seen. These rules are only
what's has been used for most existing code, not necessarily what
I prefer.

As for the Perl code style, I know the subject is even more hot
since so many code styles exist, but I think it's also important.

These rules might end up as a chapter on the gtk2-perl website,
which I plan to develop a bit more, so that people can easily
make themselves an idea on gtk2-perl, easily download source or
binary package.

Of course, all these rules can still be discussed. If we decide
to change anything, I'll perl -pi -e the sources so that we use
the new standard everywhere. But for each change, we need to
agree that the new style would be notably better, since these
rules are used for most existing code.


        C code

Example:

-=-=---=-=---=-=---=-=--
0: SV* gperl_object__list_properties(SV* object)
1: {
2:     AV* properties = newAV();
3:     guint n_props = 0, i;
4:     props = g_object_class_list_properties(G_OBJECT_GET_CLASS(SvGObject(object)), &n_props);
5:     for (i = 0; i < n_props; i++) {
6:         hv_store(property, "name",  4, newSVpv(g_param_spec_get_name(props[i]), 0), 0);
7:         hv_store(property, "descr", 5, newSVpv(g_param_spec_get_blurb(props[i]), 0), 0);
-=-=---=-=---=-=---=-=--

Rules:

0: don't put a newline between function type and function name
   (FYI, that's against GNU coding standard, rationale C1)
0: stick star(s) of the pointers to the type, not to the variable
   name (good: `SV* object'; bad: `SV *object')
1: opening curly of a function after a newline
2: indenting level is 4 characters
2: don't use TAB characters for indenting, use spaces; that way,
   when people view/edit the code with another tabstop as you,
   it's still indented correctly (in Emacs, set indent-tabs-mode
   to nil)
2: put one space before, and one space after, each `=' and
   similar characters (= == < > && || { })
3: no space before `,' and one space after
4: don't put a space before or after parenthesis used for calling
   functions (good: `foo("bar")'; bad: `foo ("bar")')
5: no space before `;' and one space after
5: opening curly brace of a control structure is at the end of
   line, not after a newline (rationale C1), namely `if for while
   do'
6: first instruction of a block after a newline
6-7: add spaces when it's meaningful for vertical indenting
     several lines (the two spaces before `4')

Referred rationales:

C1:
        (from Linux kernel coding styles) saves one line in
        height without much sacrificing readability; is nice
        because you can see more code in only one screen


        Perl code

Example:

-=-=---=-=---=-=---=-=--
0: sub white_gc {
1:     my ($self, $set) = @_;
2:     if (defined($set)) {
3:         $self->set_white_gc($set, 'foo');
4:         return $self->get_state;
5:     }
6:     Gtk2->update_ui;
-=-=---=-=---=-=---=-=--

Most rules for C code apply (indenting, spaces, etc). Exceptions
or things proper to Perl code are:

0: opening curly brace of a function at the end of line; this is
   different from the C style but it's more commonly seen in perl
   code, and since the function declaration in Perl doesn't
   contain any useful information (no function type and no
   function prototype), it's not a so bad idea
1: always name function parameters (exceptions: for one-liners,
   see next example, and when only one param is to be given, we
   can use `shift') (actually, create lexical variables out of
   them), it helps readability (and actually is self documented
   code)
2: always use parens when invoking functions, even for builtins
   (exceptions: print printf)
3: use simple ticks when specifying non-interpolated strings
   (good: 'foo'; bad: "foo")
4: don't use parens for method calls without parameters
6: use Class->method to invoke constructors, not method Class
   (good: Gtk2->init; bad: init Gtk2) (rationale: seems that
   `method Class' comes from the special keyword "new" of C++;
   using Class->method is more orthogonal with using
   $object->method for method calls)

One-liner example:

-=-=---=-=---=-=---=-=--
sub visible { shift->get_set('visible', @_); }
-=-=---=-=---=-=---=-=--

This is an exception to the above rule of naming function
variables.


Open questions:

1. do we use infix "if/unless" or "and/or" for short control
   structures? namely:
       $self->set_active($flag) if @_ == 2;
                or
       @_ == 2 and $self->set_active($flag);

   I personally prefer "and/or" for two reasons:
   - the condition is on the left, the code to execute is on the
     right, it's more similar to doing if (condition) { .. } when
     the code to execute has many lines
   - I find "unless" very unreadable

   But I know that many people tend to line infix "if", so that's
   why I ask you to choose.

2. for one-lines, do we use `shift' or do we name the parameters
   using $_[0], $_[1], etc? I don't have an opinion here. Using
   `shift' can be better because then you can use @_ for the
   parameters of the functions, with any number of parameters.

3. do we use "return" at the end of functions? I'd choose not
   (it's useless) but most people don't like that, it seems.

Probably many others I've forgotten. Please don't hesitate to
open other questions.


Thanks.

-- 
Guillaume Cottenceau - http://people.mandrakesoft.com/~gc/



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