xref: /openbsd/usr.sbin/pkg_add/OpenBSD/style.pod (revision b49820e1)
1*b49820e1Sjsg$OpenBSD: style.pod,v 1.3 2023/09/12 09:01:04 jsg Exp $
26e49571cSdaniel
36e49571cSdaniel=head1 NAME
46e49571cSdaniel
56e49571cSdanielOpenBSD::style - Perl source file style guide
66e49571cSdaniel
76e49571cSdaniel=head1 DESCRIPTION
86e49571cSdaniel
96e49571cSdanielThis file specifies the preferred style for Perl source files
106e49571cSdanielin the OpenBSD source tree.
116e49571cSdaniel
126e49571cSdanielThe suggestions in L<style(9)> also apply as far as they make sense
136e49571cSdanielfor Perl code and unless they are overridden in the present manual page.
146e49571cSdaniel
156e49571cSdanielJust as for L<style(9)>, indentation is an 8 character tab,
166e49571cSdanieland statements continuing on the next line are indented
176e49571cSdanielby four more spaces.
186e49571cSdaniel
19f533925aSespieSystematically C<use v5.36> or later which yields C<strict>, C<warnings>,
20f533925aSespieC<say> and function signatures.
21f533925aSespie
226e49571cSdaniel=head2 Subroutines and methods
236e49571cSdaniel
246e49571cSdanielPrefer object-oriented over procedural style for new code.
256e49571cSdanielDefine a package under either C<OpenBSD::> or C<DPB::>.
266e49571cSdanielIf no state variables are needed, call methods directly on the class name.
276e49571cSdanielOtherwise, define the state variables as member variables
286e49571cSdanieland call methods on a constructed object.
296e49571cSdanielName the constructor new() unless there are better options.
306e49571cSdaniel
316e49571cSdaniel	my $pkgpath = DPB::PkgPath->new('devel/quirks');
326e49571cSdaniel	say "Normalized version is ", $pkgpath->fullpkgpath;
336e49571cSdaniel
346e49571cSdaniel	$state->errsay(OpenBSD::Temp->last_error);
356e49571cSdaniel
366e49571cSdanielInside methods, call the object C<$self> unless there are reasons not to.
376e49571cSdaniel
38f533925aSespieUse signatures for every function (except delegations), so that the number
39f533925aSespieof parameters can be checked.
406e49571cSdaniel
41f533925aSespie	sub m3($self, $p1, $p2)
426e49571cSdaniel	{
436e49571cSdaniel		...
446e49571cSdaniel	}
456e49571cSdaniel
46f533925aSespieAccordingly, avoid calling code refs without parentheses, since this creates
47f533925aSespiean implicit C<@_> reference.
486e49571cSdaniel
49f533925aSespieNote that signatures can also absorb an arbitrary number of parameters with
50f533925aSespieC<@l> and set default parameter values like in C++, e.g.
516e49571cSdaniel
52f533925aSespie	sub do_backsubst($subst, $string, $unsubst = undef,
53f533925aSespie	    $context = 'OpenBSD::PackingElement');
546e49571cSdaniel
55f533925aSespieFor methods that take no argument apart from the object itself, remove
56f533925aSespietrailing parentheses for the method call:
576e49571cSdaniel
586e49571cSdaniel	my $columns = $object->width;
596e49571cSdaniel
606e49571cSdanielIf a function passes on an arbitrary number of arguments
616e49571cSdanielto another function:
626e49571cSdaniel
63f533925aSespie	sub wrapper_method($self, @p)
646e49571cSdaniel	{
656e49571cSdaniel		...
66f533925aSespie		do_something_with(@p);
676e49571cSdaniel	}
686e49571cSdaniel
69f533925aSespieAnonymous subs should also use signatures
706e49571cSdaniel
71f533925aSespie	$state->{opt}{x} =
72f533925aSespie	    sub($opt) {
73f533925aSespie		push ${$state->{xlist}}, $opt);
74f533925aSespie	    };
75f533925aSespie
76f533925aSespie(Exception: signal handlers are currently not specified and may take an
77f533925aSespiearbitrary number of parameters for C<__DIE__> and C<__WARN__>.
78f533925aSespie
79f533925aSespieMark the last expression at the end of a function with an explicit
80*b49820e1SjsgB<return> unless the function is not intended to return anything,
81f533925aSespieor for "constant" methods
82f533925aSespie
83f533925aSespie	sub isFile($)
84f533925aSespie	{
85f533925aSespie		1;
86f533925aSespie	}
87f533925aSespie
88f533925aSespieDo not name parameters to methods unless actually used.
89f533925aSespieFor documentation, use a comment in that case (especially useful
90f533925aSespiefor base methods)
91f533925aSespie
92f533925aSespie	# $self->foo($state):
93f533925aSespie	# 	explain what foo does
94f533925aSespie	sub foo($, $)
95f533925aSespie	{
96f533925aSespie	}
97f533925aSespie
98f533925aSespieAvoid using old-style function prototypes unless absolutely necessary
99f533925aSespieto create syntax:
100f533925aSespie
101f533925aSespie	sub try :prototype(&@)
102f533925aSespie	{
103f533925aSespie		my ($try, $catch) = @_;
104f533925aSespie		eval { &$try() };
105f533925aSespie		dienow($@, $catch);
106f533925aSespie	}
107f533925aSespie
108f533925aSespieOnly use the wantarray() built-in as an optimization;
109f533925aSespieit should never change the semantics of the subroutine.
1106e49571cSdanielFor example, suppose there is a function returning a list,
1116e49571cSdanieland while the question whether the list is empty sometimes
1126e49571cSdanielneeds to be asked, the number of elements never matters.
1136e49571cSdanielSuch a function can be structured and used as follows:
1146e49571cSdaniel
1156e49571cSdaniel	sub get_list
1166e49571cSdaniel	{
1176e49571cSdaniel		if (wantarray) {
1186e49571cSdaniel			# build the complete list and return it
1196e49571cSdaniel		} else {
1206e49571cSdaniel			# only figure out whether the list is empty
1216e49571cSdaniel			# and return 0 if it is or 1 otherwise
1226e49571cSdaniel		}
1236e49571cSdaniel	}
1246e49571cSdaniel
1256e49571cSdaniel	if (get_list) {
1266e49571cSdaniel		# do something that doesn't need the actual elements
1276e49571cSdaniel	}
1286e49571cSdaniel
1296e49571cSdanielLet methods that tweak an object return the object itself,
1306e49571cSdanielsuch that methods can be chained:
1316e49571cSdaniel
1326e49571cSdaniel	$object->polish->paint('blue')->attach(@decorations);
1336e49571cSdaniel
1346e49571cSdanielSince there are no access control restrictions in Perl,
1356e49571cSdanielsimply mark internal methods by prefixing their names with C<_>.
1366e49571cSdaniel
1376e49571cSdanielTreat anonymous subroutines just like other code,
1386e49571cSdanielindenting them by one tab:
1396e49571cSdaniel
140f533925aSespie	my $s = sub($self) {
1416e49571cSdaniel		...
1426e49571cSdaniel		};
1436e49571cSdaniel
1446e49571cSdanielWhen passing an anonymous function as an argument, start it on a new line:
1456e49571cSdaniel
1466e49571cSdaniel	f($a1, $a2,
147f533925aSespie	    sub($self) {
1486e49571cSdaniel		...
1496e49571cSdaniel		});
1506e49571cSdaniel
1516e49571cSdaniel=head2 Files and packages
1526e49571cSdaniel
1536e49571cSdanielPutting several closely related classes
1546e49571cSdanielinto the same source file is fine.
1556e49571cSdaniel
1566e49571cSdanielAvoid multiple inheritance unless absolutely necessary
1576e49571cSdanielbecause it almost always turns into a mess.
1586e49571cSdanielIncluding some behavior from a different class (mixin)
159f533925aSespieis best done on a per-method basis, but explicitly annotate the mixins
160f533925aSespieas such.
161f533925aSespie
1626e49571cSdanielDelegating from one method of one class to a method of another class,
1636e49571cSdanielpassing C<@_> completely unchanged, can be done with the following syntax:
1646e49571cSdaniel
1656e49571cSdaniel	package Borrower;
1666e49571cSdaniel
1676e49571cSdaniel	sub visit_notary
1686e49571cSdaniel	{
1696e49571cSdaniel		&Lender::visit_notary;  # no parentheses here
1706e49571cSdaniel	}
1716e49571cSdaniel
172f533925aSespieThis is the only case where a code ref should be called without explicit
173f533925aSespieparameters, and where a method can be declared without a prototype.
174f533925aSespie
1756e49571cSdanielIf a program often uses fork(), set
1766e49571cSdaniel
1776e49571cSdaniel	$DB::inhibit_exit = 0;
1786e49571cSdaniel
1796e49571cSdanielright after each fork() and before the following exec(),
1806e49571cSdanielsuch that a user trying to debug the main program isn't
1816e49571cSdanielprompted each time one of the child processes exits.
1826e49571cSdaniel
1836e49571cSdaniel=head2 Data structures
1846e49571cSdaniel
1856e49571cSdanielAutovivification is welcome:
1866e49571cSdaniel
1876e49571cSdaniel	push @{$self->{list}}, $value;
1886e49571cSdaniel
1896e49571cSdanielis fine without defining C<$self-E<gt>{list}> first.
1906e49571cSdanielNote that
1916e49571cSdaniel
1926e49571cSdaniel	if (@{$self->{list}} > 0)
1936e49571cSdaniel
1946e49571cSdanielwill not autovivify C<$self-E<gt>{list}>,
1956e49571cSdanielso it can be used to check that the list exists and is not empty
1966e49571cSdanielwithout testing C<if (exists $self-E<gt>{list})> first.
1976e49571cSdaniel
1986e49571cSdanielDon't put quotes around hash subscripts unless necessary;
1996e49571cSdanielthey are not necessary for simple identifiers that are not keywords.
2006e49571cSdanielAvoid using keywords as hash keys.
2016e49571cSdaniel
2026e49571cSdanielAvoid needless arrows in chained lookups.
2036e49571cSdanielRather than C<$self-E<gt>{a}-E<gt>{b}>, write:
2046e49571cSdaniel
2056e49571cSdaniel	$self->{a}{b}
2066e49571cSdaniel
2076e49571cSdaniel=head2 Syntax details
2086e49571cSdaniel
2096e49571cSdanielThis style guide makes no recommendation to put parentheses
2106e49571cSdanielwhere they are not required.
2116e49571cSdanielFor example, calling built-in or prototyped functions
2126e49571cSdanieldoes not require parentheses.
2136e49571cSdaniel
2146e49571cSdanielModern Perl operators are preferred.
2156e49571cSdanielRather than C<defined $value or $value = $something;>
2166e49571cSdanielor C<$value = $something unless defined $value;>, write:
2176e49571cSdaniel
2186e49571cSdaniel	$value //= $something;
219