Note that these are all guidelines, not unbreakable rules. If you have
a really good need to break one of the rules herein, however, then it is
Note that these are all guidelines, not unbreakable rules. If you have
a really good need to break one of the rules herein, however, then it is
Note that with much of this document, it is not so much the Right Way as
it is Our Way. We need to have conventions in order to make life easier
Note that with much of this document, it is not so much the Right Way as
it is Our Way. We need to have conventions in order to make life easier
We don't always follow this guide. We are making changes throughout
our code to be in line with it. But just because we didn't do
it yet, that is no excuse. Do it anyway. :-)
We don't always follow this guide. We are making changes throughout
our code to be in line with it. But just because we didn't do
it yet, that is no excuse. Do it anyway. :-)
Any external documents, and documentation for command-line programs and
modules, should be written in POD, where appropriate. From there, they
Any external documents, and documentation for command-line programs and
modules, should be written in POD, where appropriate. From there, they
Read the perlpod manpage before writing any POD, because although POD is
not difficult, it is not what most people are used to. It is not a
regular markup language; it is just a way to make easy documentation
Read the perlpod manpage before writing any POD, because although POD is
not difficult, it is not what most people are used to. It is not a
regular markup language; it is just a way to make easy documentation
- 1.0.0 First release of RT 1
- 1.0.1 Second release of RT 1.0
- 1.0.10 etc.
- 1.1.0 First development release of RT 1.2 (or 2.0)
- 2.0.0 First release of RT 2
+ 1.0.0 First release of RT 1
+ 1.0.1 Second release of RT 1.0
+ 1.0.10 etc.
+ 1.1.0 First development release of RT 1.2 (or 2.0)
+ 2.0.0 First release of RT 2
Include any comments that are, or might be, necessary in order for
someone else to understand the code. Sometimes a simple one-line
Include any comments that are, or might be, necessary in order for
someone else to understand the code. Sometimes a simple one-line
- my @return = ($user, $form);
- push @return, $constants if $flag;
- return @return;
+ my @return = ($user, $form);
+ push @return, $constants if $flag;
+ return @return;
Although, usually, this is better (faster, easier to read, etc.):
Although, usually, this is better (faster, easier to read, etc.):
Perl built-in system calls return the error in $!; some functions in
modules might return an error in $@ or some other way, so read the module's
documentation if you don't know. Always do something, even if it is
Perl built-in system calls return the error in $!; some functions in
modules might return an error in $@ or some other way, so read the module's
documentation if you don't know. Always do something, even if it is
"system users" are user
names on the operating system. "database users" are the user names in
the database server. None of these needs to be capitalized.
"system users" are user
names on the operating system. "database users" are the user names in
the database server. None of these needs to be capitalized.
Constants are in all caps; these are variables whose value will I<never>
change during the course of the program.
Constants are in all caps; these are variables whose value will I<never>
change during the course of the program.
They words used should, in general, form a noun (usually singular),
unless the variable is a flag used to denote some action that should be
taken, in which case they should be verbs (or gerunds, as appropriate)
describing that action.
They words used should, in general, form a noun (usually singular),
unless the variable is a flag used to denote some action that should be
taken, in which case they should be verbs (or gerunds, as appropriate)
describing that action.
- $thisVar = 'foo'; # wrong
- $this_var = 'foo'; # right
- $work_hard = 1; # right, verb, boolean flag
- $running_fast = 0; # right, gerund, boolean flag
+ $thisVar = 'foo'; # wrong
+ $this_var = 'foo'; # right
+ $work_hard = 1; # right, verb, boolean flag
+ $running_fast = 0; # right, gerund, boolean flag
Arrays and hashes should be plural nouns, whether as regular arrays and
hashes or array and hash references. Do not name references with "ref"
or the data type in the name.
Arrays and hashes should be plural nouns, whether as regular arrays and
hashes or array and hash references. Do not name references with "ref"
or the data type in the name.
- @stories = (1, 2, 3); # right
- $comment_ref = [4, 5, 6]; # wrong
- $comments = [4, 5, 6]; # right
- $comment = $comments->[0]; # right
+ @stories = (1, 2, 3); # right
+ $comment_ref = [4, 5, 6]; # wrong
+ $comments = [4, 5, 6]; # right
+ $comment = $comments->[0]; # right
Make the name descriptive. Don't use variables like "$sc" when you
could call it "$story_count". See L<"Comments">.
Make the name descriptive. Don't use variables like "$sc" when you
could call it "$story_count". See L<"Comments">.
anything other than how they are normally used, and do not use any
other variable names in their place. Some of these are:
anything other than how they are normally used, and do not use any
other variable names in their place. Some of these are:
Subroutines (except for special cases, like AUTOLOAD and simple accessors)
begin with a verb, with words following to complete the action. Accessors
Subroutines (except for special cases, like AUTOLOAD and simple accessors)
begin with a verb, with words following to complete the action. Accessors
Words begin with a capital letter. They
should as clearly as possible describe the activity to be peformed, and
Words begin with a capital letter. They
should as clearly as possible describe the activity to be peformed, and
Subroutines beginning with C<_> are special: they are not to be used
outside the current object. There is not to be enforced by the code
Subroutines beginning with C<_> are special: they are not to be used
outside the current object. There is not to be enforced by the code
Note that the special variable C<_> I<should> be used when possible.
It is a placeholder that can be passed to stat() and the file test
Note that the special variable C<_> I<should> be used when possible.
It is a placeholder that can be passed to stat() and the file test
C<_> for subsequent uses, is a performance hit. You should be
careful that the last-tested file is what you think it is, though.
C<_> for subsequent uses, is a performance hit. You should be
careful that the last-tested file is what you think it is, though.
Package names begin with a capital letter in each word, followed by
lower case letters (for the most part). Multiple words should be StudlyCapped.
Package names begin with a capital letter in each word, followed by
lower case letters (for the most part). Multiple words should be StudlyCapped.
- RT::User # good
- RT::Database::MySQL # proper name
- RT::Display::Provider # good
- RT::CustomField # not so good, but OK
+ RT::User # good
+ RT::Database::MySQL # proper name
+ RT::Display::Provider # good
+ RT::CustomField # not so good, but OK
- open(FILE, $fh) or die $!;
- open(FILE2, $fh2) or die $!;
+ open(FILE, $fh) or die $!;
+ open(FILE2, $fh2) or die $!;
Put blank lines between groups of code that do different things. Put
blank lines after your variable declarations. Put a blank line before a
Put blank lines between groups of code that do different things. Put
blank lines after your variable declarations. Put a blank line before a
For control structures, there is a space between the keyword and opening
parenthesis. For functions, there is not.
For control structures, there is a space between the keyword and opening
parenthesis. For functions, there is not.
- my @array = ('a', 'b', 'c');
- my($first_element) = @array; # a
- my($first_element) = ('a', 'b', 'c'); # a
- my $element_count = @array; # 3
- my $last_element = ('a', 'b', 'c'); # c
+ my @array = ('a', 'b', 'c');
+ my($first_element) = @array; # a
+ my($first_element) = ('a', 'b', 'c'); # a
+ my $element_count = @array; # 3
+ my $last_element = ('a', 'b', 'c'); # c
Always include parentheses after functions, even if there are no arguments.
There are some exceptions, such as list operators (like print) and unary
Always include parentheses after functions, even if there are no arguments.
There are some exceptions, such as list operators (like print) and unary
- for ( map { [ $_, 1 ] } @list ) # OK
- for ( @list ) # not really OK, not horrible
+ for ( map { [ $_, 1 ] } @list ) # OK
+ for ( @list ) # not really OK, not horrible
On multi-line expressions, match up the closing parenthesis with either
the opening statement, or the opening parenthesis, whichever works best.
Examples:
On multi-line expressions, match up the closing parenthesis with either
the opening statement, or the opening parenthesis, whichever works best.
Examples:
Whether or not there is space following a closing parenthesis is
dependent on what it is that follows.
Whether or not there is space following a closing parenthesis is
dependent on what it is that follows.
Note also that parentheses around single-statement control expressions,
as in C<if $xyzzy>, are optional (and discouraged) C<if> it is I<absolutely>
Note also that parentheses around single-statement control expressions,
as in C<if $xyzzy>, are optional (and discouraged) C<if> it is I<absolutely>
However, if there is any possible confusion at all, then include the
parentheses. Remember the words of Larry Wall in the perlstyle manpage:
However, if there is any possible confusion at all, then include the
parentheses. Remember the words of Larry Wall in the perlstyle manpage:
- When in doubt, parenthesize. At the very least it will
- let some poor schmuck bounce on the % key in vi.
+ When in doubt, parenthesize. At the very least it will
+ let some poor schmuck bounce on the % key in vi.
- Even if you aren't in doubt, consider the mental welfare
- of the person who has to maintain the code after you, and
- who will probably put parens in the wrong place.
+ Even if you aren't in doubt, consider the mental welfare
+ of the person who has to maintain the code after you, and
+ who will probably put parens in the wrong place.
So leave them out when it is absoutely clear to a programmer, but if
there is any question, leave them in.
So leave them out when it is absoutely clear to a programmer, but if
there is any question, leave them in.
Otherwise, finish each statement with a semicolon, put the keyword and
opening curly on the first line, and the ending curly lined up with the
keyword at the end.
Otherwise, finish each statement with a semicolon, put the keyword and
opening curly on the first line, and the ending curly lined up with the
keyword at the end.
aesthetics; e.g., sometimes the space around "**" is ommitted,
and there is never a space before a ",", but always after.
aesthetics; e.g., sometimes the space around "**" is ommitted,
and there is never a space before a ",", but always after.
Other than that, they are exactly the same. It is best to use the lower
precedence version for control, and the higher for testing/returning
values. Examples:
Other than that, they are exactly the same. It is best to use the lower
precedence version for control, and the higher for testing/returning
values. Examples:
- $bool = $flag1 or $flag2; # WRONG (doesn't work)
- $value = $foo || $bar; # right
- open(FILE, $file) or die $!;
+ $bool = $flag1 or $flag2; # WRONG (doesn't work)
+ $value = $foo || $bar; # right
+ open(FILE, $file) or die $!;
Note that "and" is seldom ever used, because the statement above is
better written using "if":
Note that "and" is seldom ever used, because the statement above is
better written using "if":
Most of the time, the confusion between and/&&, or/|| can be alleviated
by using parentheses. If you want to leave off the parentheses then you
Most of the time, the confusion between and/&&, or/|| can be alleviated
by using parentheses. If you want to leave off the parentheses then you
Try to keep the two parts to a binary operator (an operator that
has two operands) together when possible.
Try to keep the two parts to a binary operator (an operator that
has two operands) together when possible.
It is OK to omit quotes around names in braces and when using
the => operator, but be careful not to use a name that doubles as
a function; in that case, quote.
It is OK to omit quotes around names in braces and when using
the => operator, but be careful not to use a name that doubles as
a function; in that case, quote.
- open(FILE, $fh) or die $!; # right
- die $! unless open(FILE, $fh); # wrong
+ open(FILE, $fh) or die $!; # right
+ die $! unless open(FILE, $fh); # wrong
- print <<EOT;
- This is a whole bunch of text.
- I like it. I don't need to worry about messing
- with lots of print statements and lining them up.
- EOT
+ print <<EOT;
+ This is a whole bunch of text.
+ I like it. I don't need to worry about messing
+ with lots of print statements and lining them up.
+ EOT
Just remember that unless you put single quotes around your here-doc
token (<<'EOT'), the text will be interpolated, so escape any "$" or "@"
Just remember that unless you put single quotes around your here-doc
token (<<'EOT'), the text will be interpolated, so escape any "$" or "@"
-should become <&|/l, $num, $queue &>You found [_1] tickets in queue [_2]</&>
+The string You found <%$num%> tickets in queue <%$queue%>
+
+should become <&|/l, $num, $queue &>You found [_1] tickets in queue [_2]</&>
-The string <& /Elements/TitleBoxStart, width=> "40%", titleright => "RT $RT::VERSION for RT->Config->Get('rtname')", title => 'Login' &>
+The string <& /Widgets/TitleBoxStart, width=> "40%", titleright => "RT $RT::VERSION for RT->Config->Get('rtname')", title => 'Login' &>
-should become <& /Elements/TitleBoxStart,
- width=> "40%",
- titleright => loc("RT [_1] for [_2]",$RT::VERSION, RT->Config->Get('rtname')),
- title => loc('Login'),
- &>
+should become <& /Widgets/TitleBoxStart,
+ width=> "40%",
+ titleright => loc("RT [_1] for [_2]",$RT::VERSION, RT->Config->Get('rtname')),
+ title => loc('Login'),
+ &>
It is important not to localize the names of rights or statuses within RT's core, as there is logic that depends on them as string identifiers. The proper place to localize these values is when they're presented for display in the web or commandline interfaces.
It is important not to localize the names of rights or statuses within RT's core, as there is logic that depends on them as string identifiers. The proper place to localize these values is when they're presented for display in the web or commandline interfaces.
This is mostly informal, but a fairly complete explanation for the need
and use of the code should be provided.
This is mostly informal, but a fairly complete explanation for the need
and use of the code should be provided.
-approval and discussion. For web and command-line programs, present the
-functionality and interface (op codes, command-lin switches, etc.).
+discussion. For web and command-line programs, present the
+functionality and interface (op codes, command-line switches, etc.).
The best way to do this is to take the documentation portion of the
boilerplate and fill it in. You can make changes later if necessary,
The best way to do this is to take the documentation portion of the
boilerplate and fill it in. You can make changes later if necessary,
-if you do not have repository access, submit it to rt-bugs@fsck.com as a
-unified diff. From that point on, it'll be handled by someone with
-repository access.
+submit your updates as a pull request on GitHub. If you don't have a GitHub
+account, you can generate patches and send email to rt-bugs@bestpractical.com
+which will create a ticket in our public issue tracker at
+L<https://issues.bestpractical.com>.