[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 @title General Coding Standards 2 @group standards 3 4 This document is a general coding standard for contributing to Phabricator, 5 Arcanist, libphutil and Diviner. 6 7 = Overview = 8 9 This document contains practices and guidelines which apply across languages. 10 Contributors should follow these guidelines. These guidelines are not 11 hard-and-fast but should be followed unless there is a compelling reason to 12 deviate from them. 13 14 = Code Complexity = 15 16 - Prefer to write simple code which is easy to understand. The simplest code 17 is not necessarily the smallest, and some changes which make code larger 18 (such as decomposing complex expressions and choosing more descriptive 19 names) may also make it simpler. Be willing to make size tradeoffs in favor 20 of simplicity. 21 - Prefer simple methods and functions which take a small number of parameters. 22 Avoid methods and functions which are long and complex, or take an 23 innumerable host of parameters. When possible, decompose monolithic, complex 24 methods into several focused, simpler ones. 25 - Avoid putting many ideas on a single line of code. 26 27 For example, avoid this kind of code: 28 29 COUNTEREXAMPLE 30 $category_map = array_combine( 31 $dates, 32 array_map(create_function('$z', 'return date("F Y", $z);'), $dates)); 33 34 Expressing this complex transformation more simply produces more readable code: 35 36 $category_map = array(); 37 foreach ($dates as $date) { 38 $category_map[$date] = date('F Y', $date); 39 } 40 41 And, obviously, don't do this sort of thing: 42 43 COUNTEREXAMPLE 44 if ($val = $some->complicatedConstruct() && !!~blarg_blarg_blarg() & $flags 45 ? HOPE_YOU_MEMORIZED == $all_the_lexical_binding_powers : <<<'Q' 46 $hahaha} 47 Q 48 ); 49 50 51 = Performance = 52 53 - Prefer to write efficient code. 54 - Strongly prefer to drive optimization decisions with hard data. Avoid 55 optimizing based on intuition or rumor if you can not support it with 56 concrete measurements. 57 - Prefer to optimize code which is slow and runs often. Optimizing code which 58 is fast and runs rarely is usually a waste of time, and can even be harmful 59 if it makes that code more difficult to understand or maintain. You can 60 determine if code is fast or slow by measuring it. 61 - Reject performance discussions that aren't rooted in concrete data. 62 63 In Phabricator, you can usually use the builtin XHProf profiling to quickly 64 gather concrete performance data. 65 66 67 = Naming Things = 68 69 - Follow language-specific conventions. 70 - Name things unambiguously. 71 - Choose descriptive names. 72 - Avoid nonstandard abbreviations (common abbreviations like ID, URI and HTTP 73 are fine). 74 - Spell words correctly. 75 - Use correct grammar. 76 77 For example, avoid these sorts of naming choices: 78 79 COUNTEREXAMPLE 80 $PIE->GET_FLAVOR(); // Unconventional. 81 $thing->doStuff(); // Ambiguous. 82 $list->empty(); // Ambiguous -- is it isEmpty() or makeEmpty()? 83 $e = 3; // Not descriptive. 84 $this->updtHndlr(); // Nonstandard abbreviation. 85 $this->chackSpulls(); // Misspelling, ungrammatical. 86 87 Prefer these: 88 89 $pie->getFlavor(); // Conventional. 90 $pie->bake(); // Unambiguous. 91 $list->isEmpty(); // Unambiguous. 92 $list->makeEmpty(); // Unambiguous. 93 $edge_count = 3; // Descriptive. 94 $this->updateHandler(); // No nonstandard abbreviations. 95 $this->getID(); // Standard abbreviation. 96 $this->checkSpelling(); // Correct spelling and grammar. 97 98 99 = Error Handling = 100 101 - Strongly prefer to detect errors. 102 - Strongly prefer to fail fast and loudly. The maximum cost of script 103 termination is known, bounded, and fairly small. The maximum cost of 104 continuing script execution when errors have occurred is unknown and 105 unbounded. This also makes APIs much easier to use and problems far easier 106 to debug. 107 108 When you ignore errors, defer error handling, or degrade the severity of errors 109 by treating them as warnings and then dismissing them, you risk dangerous 110 behavior which may be difficult to troubleshoot: 111 112 COUNTEREXAMPLE 113 exec('echo '.$data.' > file.bak'); // Bad! 114 do_something_dangerous(); 115 116 exec('echo '.$data.' > file.bak', $out, $err); // Also bad! 117 if ($err) { 118 debug_rlog("Unable to copy file!"); 119 } 120 do_something_dangerous(); 121 122 Instead, fail loudly: 123 124 exec('echo '.$data.' > file.bak', $out, $err); // Better 125 if ($err) { 126 throw new Exception("Unable to copy file!"); 127 } 128 do_something_dangerous(); 129 130 But the best approach is to use or write an API which simplifies condition 131 handling and makes it easier to get right than wrong: 132 133 execx('echo %s > file.bak', $data); // Good 134 do_something_dangerous(); 135 136 Filesystem::writeFile('file.bak', $data); // Best 137 do_something_dangerous(); 138 139 See @{article@libphutil:Command Execution} for details on the APIs used in this 140 example. 141 142 = Documentation, Comments and Formatting = 143 144 - Prefer to remove code by deleting it over removing it by commenting it out. 145 It shall live forever in source control, and can be retrieved therefrom if 146 it is ever again called upon. 147 - In source code, use only ASCII printable characters plus space and linefeed. 148 Do not use UTF-8 or other multibyte encodings.
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |