mirror of
https://github.com/google/styleguide.git
synced 2024-03-22 13:11:43 +08:00
Update C++ style guide to 3.274:
- Change formatting rules of braced initializers. - Permit use of constexpr and allow constexpr global variables. - Allow all C++11 features except for those that are specifically banned. - Fix/add C99 format specifiers for ptrdiff_t and ssize_t. - Add lambda expressions to the list of explicitly banned C++11 features. - Relax "return type is always on the same line as the function name" rule. - Allow unique_ptr, discourage ownership transfer. Allow noncopyable std::move. - Allow system-specific includes after other includes. - Add boost/math/distributions to the set of permitted Boost libraries. Update Objective-C style guide to 2.59: - Use instancetype as return type for example init methods. - Remove invalid +stringWithInt: call. - Remove reference to pre-Objective-C 2.0 declaration requirements. - Remove reference to Objective-C exception macros. - Remove reference to informal protocols as an alternative to optional methods. - Class headers should include comments documenting non-trivial interfaces. - Don't specify that blocks are preferable to methods as callbacks. - Specify "strong" and "weak" as comments for non-Objective-C pointers. - Replace improper reference to ownership of a retained object. - Clarify some aspects of method ordering rules. - Prefixes are required for shared code and optional for applications. - Clarify that nil pointers are safe as receivers, not necessarily parameters. - Clarify that delegate pointers should typically be zeroing weak pointers. - Allow a 100-column limit, except for projects that choose to use 80. Update Python style guide to 2.59: - Add more examples of bad code to the default arguments section. - Allow ''' when ' is used as the single quote within a file. - Remove references to pychecker. Recommend pylint. - Add more examples to the indentation section. Update JavaScript style guide to 2.93: - Add @nocompile. - Fix a few typos. - When wrapping lines, indent more deeply for child expressions. - Document that @const can be used on a constructor. - Update eval section to discourage using eval for RPC. - Update an example to avoid encouraging using numbers as booleans. - Allow for no indentation of @desc jsdoc tags. - Add @public discussion. Update shell style guide to 1.26: - Add a section on style for case statements. Update Common Lisp style guide to 1.23: - fare-matcher was superseded by optima. - Clarify wording regarding DYNAMIC-EXTENT.
This commit is contained in:
parent
d6c053f670
commit
7b24563e08
804
cppguide.xml
804
cppguide.xml
File diff suppressed because it is too large
Load Diff
|
@ -3,7 +3,7 @@
|
|||
<GUIDE title="Google JavaScript Style Guide">
|
||||
<p class="revision">
|
||||
|
||||
Revision 2.82
|
||||
Revision 2.93
|
||||
</p>
|
||||
|
||||
<address>
|
||||
|
@ -78,7 +78,7 @@
|
|||
<li>Never use the
|
||||
<a href="https://developer.mozilla.org/en/JavaScript/Reference/Statements/const">
|
||||
<code>const</code> keyword</a>
|
||||
as it not supported in Internet Explorer.</li>
|
||||
as it's not supported in Internet Explorer.</li>
|
||||
</ul>
|
||||
</SUMMARY>
|
||||
<BODY>
|
||||
|
@ -112,8 +112,13 @@
|
|||
lack of support in Internet Explorer).</p>
|
||||
|
||||
<p>A <code>@const</code> annotation on a method additionally
|
||||
implies that the method should not be overridden in subclasses.
|
||||
implies that the method cannot not be overridden in subclasses.
|
||||
</p>
|
||||
|
||||
<p>A <code>@const</code> annotation on a constructor implies the
|
||||
class cannot be subclassed (akin to <code>final</code> in Java).
|
||||
</p>
|
||||
|
||||
</SUBSECTION>
|
||||
|
||||
<SUBSECTION title="Examples">
|
||||
|
@ -139,7 +144,7 @@
|
|||
overwritten.
|
||||
</p>
|
||||
|
||||
<p>The open source compiler will allow the symbol it to be
|
||||
<p>The open source compiler will allow the symbol to be
|
||||
overwritten because the constant is
|
||||
<em>not</em> marked as <code>@const</code>.</p>
|
||||
|
||||
|
@ -151,6 +156,15 @@
|
|||
MyClass.fetchedUrlCache_ = new goog.structs.Map();
|
||||
</CODE_SNIPPET>
|
||||
|
||||
<CODE_SNIPPET>
|
||||
/**
|
||||
* Class that cannot be subclassed.
|
||||
* @const
|
||||
* @constructor
|
||||
*/
|
||||
sloth.MyFinalClass = function() {};
|
||||
</CODE_SNIPPET>
|
||||
|
||||
<p>In this case, the pointer can never be overwritten, but
|
||||
value is highly mutable and <b>not</b> constant (and thus in
|
||||
<code>camelCase</code>, not <code>ALL_CAPS</code>).</p>
|
||||
|
@ -187,7 +201,7 @@
|
|||
|
||||
// 2. Trying to do one thing on Internet Explorer and another on Firefox.
|
||||
// I know you'd never write code like this, but throw me a bone.
|
||||
[normalVersion, ffVersion][isIE]();
|
||||
[ffVersion, ieVersion][isIE]();
|
||||
|
||||
|
||||
var THINGS_TO_EAT = [apples, oysters, sprayOnCheese] // No semicolon here.
|
||||
|
@ -202,11 +216,12 @@
|
|||
"called" resulting in an error.</li>
|
||||
<li>You will most likely get a 'no such property in undefined'
|
||||
error at runtime as it tries to call
|
||||
<code>x[ffVersion][isIE]()</code>.</li>
|
||||
<li><code>die</code> is called unless
|
||||
<code>resultOfOperation()</code> is <code>NaN</code> and
|
||||
<code>THINGS_TO_EAT</code> gets assigned the result of
|
||||
<code>die()</code>.</li>
|
||||
<code>x[ffVersion, ieVersion][isIE]()</code>.</li>
|
||||
<li><code>die</code> is always called since the array minus 1 is
|
||||
<code>NaN</code> which is never equal to anything (not even if
|
||||
<code>resultOfOperation()</code> returns <code>NaN</code>) and
|
||||
<code>THINGS_TO_EAT</code> gets assigned the result of
|
||||
<code>die()</code>.</li>
|
||||
</ol>
|
||||
</SUBSECTION>
|
||||
<SUBSECTION title="Why?">
|
||||
|
@ -265,7 +280,7 @@
|
|||
Expression to define a function within a block:</p>
|
||||
<CODE_SNIPPET>
|
||||
if (x) {
|
||||
var foo = function() {}
|
||||
var foo = function() {};
|
||||
}
|
||||
</CODE_SNIPPET>
|
||||
</BODY>
|
||||
|
@ -343,8 +358,7 @@
|
|||
<a href="http://code.google.com/closure/library/">
|
||||
the Closure Library
|
||||
</a>
|
||||
or something similar.
|
||||
|
||||
or a similar library function.
|
||||
</p>
|
||||
<CODE_SNIPPET>
|
||||
function D() {
|
||||
|
@ -420,8 +434,7 @@
|
|||
<p>The ability to create closures is perhaps the most useful and often
|
||||
overlooked feature of JS. Here is
|
||||
<a href="http://jibbering.com/faq/faq_notes/closures.html">
|
||||
a good description of how closures work
|
||||
</a>.</p>
|
||||
a good description of how closures work</a>.</p>
|
||||
<p>One thing to keep in mind, however, is that a closure keeps a pointer
|
||||
to its enclosing scope. As a result, attaching a closure to a DOM
|
||||
element can create a circular reference and thus, a memory leak. For
|
||||
|
@ -443,7 +456,7 @@
|
|||
}
|
||||
|
||||
function bar(a, b) {
|
||||
return function() { /* uses a and b */ }
|
||||
return function() { /* uses a and b */ };
|
||||
}
|
||||
</CODE_SNIPPET>
|
||||
</BODY>
|
||||
|
@ -451,53 +464,43 @@
|
|||
|
||||
<STYLEPOINT title="eval()">
|
||||
<SUMMARY>
|
||||
Only for deserialization (e.g. evaluating RPC responses)
|
||||
Only for code loaders and REPL (Read–eval–print loop)
|
||||
</SUMMARY>
|
||||
<BODY>
|
||||
<p><code>eval()</code> makes for confusing semantics and is dangerous
|
||||
to use if the string being <code>eval()</code>'d contains user input.
|
||||
There's usually a better, more clear, safer way to write your code, so
|
||||
its use is generally not permitted. However <code>eval</code> makes
|
||||
deserialization considerably easier than the non-<code>eval</code>
|
||||
alternatives, so its use is acceptable for this task (for example, to
|
||||
evaluate RPC responses).</p>
|
||||
<p>Deserialization is the process of transforming a series of bytes into
|
||||
an in-memory data structure. For example, you might write objects out
|
||||
to a file as:</p>
|
||||
There's usually a better, clearer, and safer way to write your code,
|
||||
so its use is generally not permitted.</p>
|
||||
|
||||
<p>For RPC you can always use JSON and read the result using
|
||||
<code>JSON.parse()</code> instead of <code>eval()</code>.</p>
|
||||
|
||||
<p>Let's assume we have a server that returns something like this:</p>
|
||||
|
||||
<CODE_SNIPPET>
|
||||
users = [
|
||||
{
|
||||
name: 'Eric',
|
||||
id: 37824,
|
||||
email: 'jellyvore@myway.com'
|
||||
},
|
||||
{
|
||||
name: 'xtof',
|
||||
id: 31337,
|
||||
email: 'b4d455h4x0r@google.com'
|
||||
},
|
||||
...
|
||||
];
|
||||
</CODE_SNIPPET>
|
||||
<p>Reading these data back into memory is as simple as
|
||||
<code>eval</code>ing the string representation of the file.</p>
|
||||
<p>Similarly, <code>eval()</code> can simplify decoding RPC return
|
||||
values. For example, you might use an <code>XMLHttpRequest</code>
|
||||
to make an RPC, and in its response the server can return
|
||||
JavaScript:</p>
|
||||
<CODE_SNIPPET>
|
||||
var userOnline = false;
|
||||
var user = 'nusrat';
|
||||
var xmlhttp = new XMLHttpRequest();
|
||||
xmlhttp.open('GET', 'http://chat.google.com/isUserOnline?user=' + user, false);
|
||||
xmlhttp.send('');
|
||||
// Server returns:
|
||||
// userOnline = true;
|
||||
if (xmlhttp.status == 200) {
|
||||
eval(xmlhttp.responseText);
|
||||
{
|
||||
"name": "Alice",
|
||||
"id": 31502,
|
||||
"email": "looking_glass@example.com"
|
||||
}
|
||||
// userOnline is now true.
|
||||
</CODE_SNIPPET>
|
||||
|
||||
<BAD_CODE_SNIPPET>
|
||||
var userInfo = eval(feed);
|
||||
var email = userInfo['email'];
|
||||
</BAD_CODE_SNIPPET>
|
||||
|
||||
<p>If the feed was modified to include malicious JavaScript code, then
|
||||
if we use <code>eval</code> then that code will be executed.</p>
|
||||
|
||||
<CODE_SNIPPET>
|
||||
var userInfo = JSON.parse(feed);
|
||||
var email = userInfo['email'];
|
||||
</CODE_SNIPPET>
|
||||
|
||||
<p>With <code>JSON.parse</code>, invalid JSON (including all executable
|
||||
JavaScript) will cause an exception to be thrown.</p>
|
||||
|
||||
</BODY>
|
||||
</STYLEPOINT>
|
||||
|
||||
|
@ -768,7 +771,6 @@
|
|||
* WRONG -- Do NOT do this.
|
||||
*/
|
||||
var foo = { get next() { return this.nextId++; } };
|
||||
};
|
||||
</BAD_CODE_SNIPPET>
|
||||
</SUBSECTION>
|
||||
|
||||
|
@ -1080,8 +1082,8 @@
|
|||
// ...
|
||||
}
|
||||
|
||||
// Parenthesis-aligned, one argument per line. Visually groups and
|
||||
// emphasizes each individual argument.
|
||||
// Parenthesis-aligned, one argument per line. Emphasizes each
|
||||
// individual argument.
|
||||
function bar(veryDescriptiveArgumentNumberOne,
|
||||
veryDescriptiveArgumentTwo,
|
||||
tableModelEventHandlerProxy,
|
||||
|
@ -1184,13 +1186,14 @@
|
|||
}); // goog.scope
|
||||
</CODE_SNIPPET>
|
||||
</SUBSECTION>
|
||||
<SUBSECTION title="More Indentation">
|
||||
<p>In fact, except for
|
||||
<a href="#Array_and_Object_literals">
|
||||
array and object initializers
|
||||
</a>, and passing anonymous functions, all wrapped lines
|
||||
should be indented either left-aligned to the expression above, or
|
||||
indented four spaces, not indented two spaces.</p>
|
||||
<SUBSECTION title="Indenting wrapped lines">
|
||||
<p>Except for <a href="#Array_and_Object_literals">array literals,
|
||||
object literals</a>, and anonymous functions, all wrapped lines
|
||||
should be indented either left-aligned to a sibling expression
|
||||
above, or four spaces (not two spaces) deeper than a parent
|
||||
expression (where "sibling" and "parent" refer to parenthesis
|
||||
nesting level).
|
||||
</p>
|
||||
|
||||
<CODE_SNIPPET>
|
||||
someWonderfulHtml = '<div class="' + getClassesForWonderfulHtml()'">' +
|
||||
|
@ -1202,8 +1205,13 @@
|
|||
thisIsAVeryLongVariableName =
|
||||
hereIsAnEvenLongerOtherFunctionNameThatWillNotFitOnPrevLine();
|
||||
|
||||
thisIsAVeryLongVariableName = 'expressionPartOne' + someMethodThatIsLong() +
|
||||
thisIsAnEvenLongerOtherFunctionNameThatCannotBeIndentedMore();
|
||||
thisIsAVeryLongVariableName = siblingOne + siblingTwo + siblingThree +
|
||||
siblingFour + siblingFive + siblingSix + siblingSeven +
|
||||
moreSiblingExpressions + allAtTheSameIndentationLevel;
|
||||
|
||||
thisIsAVeryLongVariableName = operandOne + operandTwo + operandThree +
|
||||
operandFour + operandFive * (
|
||||
aNestedChildExpression + shouldBeIndentedMore);
|
||||
|
||||
someValue = this.foo(
|
||||
shortArg,
|
||||
|
@ -2208,8 +2216,7 @@
|
|||
<p>
|
||||
We follow the
|
||||
<a href="cppguide.xml#Comments">
|
||||
C++ style for comments
|
||||
</a> in spirit.
|
||||
C++ style for comments</a> in spirit.
|
||||
</p>
|
||||
|
||||
<p>All files, classes, methods and properties should be documented with
|
||||
|
@ -2229,9 +2236,8 @@
|
|||
<SUBSECTION title="Comment Syntax">
|
||||
<p>The JSDoc syntax is based on
|
||||
<a href="http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html">
|
||||
JavaDoc
|
||||
</a>. Many tools extract metadata from JSDoc comments to perform
|
||||
code validation and optimizations. These comments must be
|
||||
JavaDoc</a>. Many tools extract metadata from JSDoc comments to
|
||||
perform code validation and optimizations. These comments must be
|
||||
well-formed.</p>
|
||||
|
||||
<CODE_SNIPPET>
|
||||
|
@ -2260,7 +2266,8 @@
|
|||
};
|
||||
</CODE_SNIPPET>
|
||||
|
||||
<p>You should not indent the <code>@fileoverview</code> command.</p>
|
||||
<p>You should not indent the <code>@fileoverview</code> command. You do not have to
|
||||
indent the <code>@desc</code> command.</p>
|
||||
|
||||
<p>Even though it is not preferred, it is also acceptable to line up
|
||||
the description.</p>
|
||||
|
@ -2476,14 +2483,14 @@
|
|||
*/
|
||||
mynamespace.Request.prototype.initialize = function() {
|
||||
// This method cannot be overridden in a subclass.
|
||||
}
|
||||
};
|
||||
</CODE_SNIPPET>
|
||||
</td>
|
||||
<td>
|
||||
<p>Marks a variable (or property) as read-only and suitable
|
||||
for inlining.</p>
|
||||
|
||||
<p>A <code>@const</code> variable is a immutable pointer to
|
||||
<p>A <code>@const</code> variable is an immutable pointer to
|
||||
a value. If a variable or property marked as
|
||||
<code>@const</code> is overwritten, JSCompiler will give
|
||||
warnings.</p>
|
||||
|
@ -2532,7 +2539,10 @@
|
|||
/** @define {boolean} */
|
||||
var TR_FLAGS_ENABLE_DEBUG = true;
|
||||
|
||||
/** @define {boolean} */
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that
|
||||
* the browser is IE.
|
||||
*/
|
||||
goog.userAgent.ASSUME_IE = false;
|
||||
</CODE_SNIPPET>
|
||||
</td>
|
||||
|
@ -2902,6 +2912,27 @@
|
|||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><a name="tag-nocompile">@nocompile</a></td>
|
||||
<td>
|
||||
<code>@nocompile</code>
|
||||
<p><i>For example:</i></p>
|
||||
<CODE_SNIPPET>
|
||||
/** @nocompile */
|
||||
|
||||
// JavaScript code
|
||||
</CODE_SNIPPET>
|
||||
</td>
|
||||
<td>
|
||||
Used at the top of a file to tell the compiler to parse this
|
||||
file but not compile it.
|
||||
Code that is not meant for compilation and should be omitted
|
||||
from compilation tests (such as bootstrap code) uses this
|
||||
annotation.
|
||||
Use sparingly.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><a name="tag-nosideeffects">@nosideeffects</a></td>
|
||||
<td>
|
||||
|
@ -2911,7 +2942,7 @@
|
|||
/** @nosideeffects */
|
||||
function noSideEffectsFn1() {
|
||||
// ...
|
||||
};
|
||||
}
|
||||
|
||||
/** @nosideeffects */
|
||||
var noSideEffectsFn2 = function() {
|
||||
|
@ -2943,7 +2974,7 @@
|
|||
* @return {string} Human-readable representation of project.SubClass.
|
||||
* @override
|
||||
*/
|
||||
project.SubClass.prototype.toString() {
|
||||
project.SubClass.prototype.toString = function() {
|
||||
// ...
|
||||
};
|
||||
</CODE_SNIPPET>
|
||||
|
@ -3000,9 +3031,7 @@
|
|||
<td>
|
||||
Used in conjunction with a trailing underscore on the method
|
||||
or property name to indicate that the member is
|
||||
<a href="#Visibility__private_and_protected_fields_">private</a>.
|
||||
Trailing underscores may eventually be deprecated as tools are
|
||||
updated to enforce <code>@private</code>.
|
||||
<a href="#Visibility__private_and_protected_fields_">private</a> and final.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
@ -3014,8 +3043,7 @@
|
|||
<p><i>For example:</i></p>
|
||||
<CODE_SNIPPET>
|
||||
/**
|
||||
* Sets the component's root element to the given element. Considered
|
||||
* protected and final.
|
||||
* Sets the component's root element to the given element.
|
||||
* @param {Element} element Root element for the component.
|
||||
* @protected
|
||||
*/
|
||||
|
@ -3032,6 +3060,30 @@
|
|||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><a name="tag-public">@public</a></td>
|
||||
<td>
|
||||
<code>@public</code><br/>
|
||||
<code>@public {type}</code>
|
||||
<p><i>For example:</i></p>
|
||||
<CODE_SNIPPET>
|
||||
/**
|
||||
* Whether to cancel the event in internal capture/bubble processing.
|
||||
* @public {boolean}
|
||||
* @suppress {visiblity} Referencing this outside this package is strongly
|
||||
* discouraged.
|
||||
*/
|
||||
goog.events.Event.prototype.propagationStopped_ = false;
|
||||
</CODE_SNIPPET>
|
||||
</td>
|
||||
<td>
|
||||
Used to indicate that the member or property is public. Variables and
|
||||
properties are public by default, so this annotation is rarely necessary.
|
||||
Should only be used in legacy code that cannot be easily changed to
|
||||
override the visibility of members that were named as private variables.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><a name="tag-return">@return</a></td>
|
||||
<td>
|
||||
|
@ -3136,6 +3188,9 @@
|
|||
<code>
|
||||
@suppress {warning1|warning2}
|
||||
</code>
|
||||
<code>
|
||||
@suppress {warning1,warning2}
|
||||
</code>
|
||||
<p><i>For example:</i></p>
|
||||
<CODE_SNIPPET>
|
||||
/**
|
||||
|
@ -3148,7 +3203,7 @@
|
|||
</td>
|
||||
<td>
|
||||
Suppresses warnings from tools. Warning categories are
|
||||
separated by <code>|</code>.
|
||||
separated by <code>|</code> or <code>,</code>.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -3166,7 +3221,7 @@
|
|||
* @template T
|
||||
*/
|
||||
goog.bind = function(fn, thisObj, var_args) {
|
||||
...
|
||||
...
|
||||
};
|
||||
</CODE_SNIPPET>
|
||||
</td>
|
||||
|
@ -3413,7 +3468,7 @@
|
|||
<SUBSECTION title="Conditional (Ternary) Operator (?:)">
|
||||
<p>Instead of this:</p>
|
||||
<CODE_SNIPPET>
|
||||
if (val != 0) {
|
||||
if (val) {
|
||||
return foo();
|
||||
} else {
|
||||
return bar();
|
||||
|
@ -3557,7 +3612,7 @@
|
|||
</PARTING_WORDS>
|
||||
|
||||
<p align="right">
|
||||
Revision 2.82
|
||||
Revision 2.93
|
||||
</p>
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
<p align="right">
|
||||
|
||||
Revision 1.22
|
||||
Revision 1.23
|
||||
</p>
|
||||
|
||||
|
||||
|
@ -74,7 +74,8 @@ Robert Brown
|
|||
<a HREF="http://www.gigamonkeys.com/book/">Practical Common Lisp</a>.
|
||||
For a language reference, please consult the
|
||||
<a HREF="http://www.lispworks.com/documentation/HyperSpec/Front/index.htm">Common Lisp HyperSpec</a>.
|
||||
For more detailed style guidance, take a look at Peter Norvig and Kent Pitman's
|
||||
For more detailed style guidance, take (with a pinch of salt)
|
||||
a look at Peter Norvig and Kent Pitman's
|
||||
<a HREF="http://norvig.com/luv-slides.ps">style guide</a>.
|
||||
</p>
|
||||
</CATEGORY>
|
||||
|
@ -2707,7 +2708,7 @@ Robert Brown
|
|||
instead of <code>FIRST</code> and <code>REST</code> also makes sense.
|
||||
However, keep in mind that it might be more appropriate in such cases
|
||||
to use higher-level constructs such as
|
||||
<code>DESTRUCTURING-BIND</code> or <code>FARE-MATCHER:MATCH</code>.
|
||||
<code>DESTRUCTURING-BIND</code> or <code>OPTIMA:MATCH</code>.
|
||||
</p>
|
||||
</BODY>
|
||||
</STYLEPOINT>
|
||||
|
@ -3348,12 +3349,12 @@ Robert Brown
|
|||
</SUMMARY>
|
||||
<BODY>
|
||||
<p>
|
||||
<code>DYNAMIC-EXTENT</code> declaration are
|
||||
<code>DYNAMIC-EXTENT</code> declarations are
|
||||
a particular case of
|
||||
<a href="#Unsafe_Operations">unsafe operations</a>.
|
||||
</p>
|
||||
<p>
|
||||
The purpose of the <code>DYNAMIC-EXTENT</code> declaration
|
||||
The purpose of a <code>DYNAMIC-EXTENT</code> declaration
|
||||
is to improve performance by reducing garbage collection
|
||||
in cases where it appears to be obvious that an object's lifetime
|
||||
is within the "dynamic extent" of a function.
|
||||
|
@ -3380,7 +3381,7 @@ Robert Brown
|
|||
The lists created to store <code>&REST</code> parameters.
|
||||
</li>
|
||||
<li>
|
||||
Lists and vector allocated within a function.
|
||||
Lists, vectors and structures allocated within a function.
|
||||
</li>
|
||||
<li>
|
||||
Closures.
|
||||
|
@ -3390,8 +3391,8 @@ Robert Brown
|
|||
If the assertion is wrong, i.e. if the programmer's claim is not true,
|
||||
the results can be <em>catastrophic</em>:
|
||||
Lisp can terminate any time after the function returns,
|
||||
or it hang forever, or — worst of all —
|
||||
produce incorrect results without any runtime error!
|
||||
or it can hang forever, or — worst of all —
|
||||
it can produce incorrect results without any runtime error!
|
||||
</p>
|
||||
<p>
|
||||
Even if the assertion is correct,
|
||||
|
@ -3433,18 +3434,19 @@ Robert Brown
|
|||
by analyzing where the function is called and
|
||||
what other functions it is passed to;
|
||||
therefore, you should somewhat wary of declaring a function
|
||||
<code>DYNAMIC-EXTENT</code>, but not a high-stress declaration.
|
||||
<code>DYNAMIC-EXTENT</code>, but this is not a high-stress declaration.
|
||||
On the other hand, it is much harder to ascertain that
|
||||
none of the objects ever bound or assigned to that variable
|
||||
and none of their sub-objects
|
||||
will escape the dynamic extent of the current call frame,
|
||||
nor will in any future modification of a function.
|
||||
and that they still won't in any future modification of a function.
|
||||
Therefore, you should be extremely wary
|
||||
of declaring a variable <code>DYNAMIC-EXTENT</code>.
|
||||
</p>
|
||||
<p>
|
||||
It's sometimes hard to know what the rate will be.
|
||||
It's usually hard to predict the effect of such optimization on performance.
|
||||
When writing a function or macro
|
||||
that's part of a library of reusable code,
|
||||
that is part of a library of reusable code,
|
||||
there's no a priori way to know how often the code will run.
|
||||
Ideally, tools would be available to discover
|
||||
the availability and suitability of using such an optimization
|
||||
|
@ -3452,7 +3454,8 @@ Robert Brown
|
|||
in practice this isn't as easy as it ought to be.
|
||||
It's a tradeoff.
|
||||
If you're very, very sure that the assertion is true
|
||||
(that the object is only used within the dynamic scope),
|
||||
(that any object bound to the variable and any of its sub-objects
|
||||
are only used within the dynamic extent of the specified scope),
|
||||
and it's not obvious how much time will be saved
|
||||
and it's not easy to measure,
|
||||
then it may be better to put in the declaration than to leave it out.
|
||||
|
@ -3474,11 +3477,16 @@ Robert Brown
|
|||
otherwise guarantees the same semantics.
|
||||
Of course, you must use <code>APPLY</code>
|
||||
if it does what you want and <code>REDUCE</code> doesn't.
|
||||
For instance:
|
||||
</p>
|
||||
<p>
|
||||
For instance, <code>(apply #'+ (mapcar #'acc frobs)</code>
|
||||
should instead be <code>(reduce #'+ frobs :key #'acc)</code>
|
||||
</p>
|
||||
<BAD_CODE_SNIPPET>
|
||||
;; Bad
|
||||
(apply #'+ (mapcar #'acc frobs))
|
||||
</BAD_CODE_SNIPPET>
|
||||
<CODE_SNIPPET>
|
||||
;; Better
|
||||
(reduce #'+ frobs :key #'acc :initial-value 0)
|
||||
</CODE_SNIPPET>
|
||||
<p>
|
||||
This is preferable because it does not do extra consing,
|
||||
and does not risk going beyond <code>CALL-ARGUMENTS-LIMIT</code>
|
||||
|
@ -3495,7 +3503,9 @@ Robert Brown
|
|||
Moreover, <code>(REDUCE 'APPEND ...)</code>
|
||||
is also <i>O(n^2)</i> unless you specify <code>:FROM-END T</code>.
|
||||
In such cases, you MUST NOT use <code>REDUCE</code>,
|
||||
but instead you MUST use proper abstractions
|
||||
and you MUST NOT use <code>(APPLY 'STRCAT ...)</code>
|
||||
or <code>(APPLY 'APPEND ...)</code> either.
|
||||
Instead you MUST use proper abstractions
|
||||
from a suitable library (that you may have to contribute to)
|
||||
that properly handles those cases
|
||||
without burdening users with implementation details.
|
||||
|
@ -3508,7 +3518,7 @@ Robert Brown
|
|||
<SUMMARY>
|
||||
You should not use <code>NCONC</code>;
|
||||
you should use <code>APPEND</code> instead,
|
||||
or better data structures.
|
||||
or better, better data structures.
|
||||
</SUMMARY>
|
||||
<BODY>
|
||||
<p>
|
||||
|
@ -3548,7 +3558,7 @@ Robert Brown
|
|||
(see Okasaki's book, and add them to lisp-interface-library),
|
||||
or more simply you should be accumulating data in a tree
|
||||
that will get flattened once in linear time
|
||||
after the accumulation phase is complete (see how ASDF does it).
|
||||
after the accumulation phase is complete.
|
||||
</p>
|
||||
<p>
|
||||
You may only use <code>NCONC</code>, <code>MAPCAN</code>
|
||||
|
@ -3639,9 +3649,9 @@ Robert Brown
|
|||
</p>
|
||||
<p>
|
||||
<code>ASDF 3</code> comes with a portability library <code>UIOP</code>
|
||||
that makes it <em>much</em> easier to deal with pathnames
|
||||
portably — and correctly — in Common Lisp.
|
||||
You should use it when appropriate.
|
||||
that makes it <em>much</em> easier to deal with pathnames
|
||||
portably — and correctly — in Common Lisp.
|
||||
You should use it when appropriate.
|
||||
</p>
|
||||
<p>
|
||||
First, be aware of the discrepancies between
|
||||
|
@ -3695,7 +3705,7 @@ Robert Brown
|
|||
You should use other pathname abstractions,
|
||||
such as <code>ASDF:SYSTEM-RELATIVE-PATHNAME</code> or
|
||||
the underlying <code>UIOP:SUBPATHNAME</code> and
|
||||
<code>UIOP:PARSE-UNIX-NAMESTRING</code>.
|
||||
<code>UIOP:PARSE-UNIX-NAMESTRING</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -3707,9 +3717,9 @@ Robert Brown
|
|||
reinitialize any search path from current environment variables.
|
||||
<code>ASDF</code> for instance requires you to reset its paths
|
||||
with <code>ASDF:CLEAR-CONFIGURATION</code>.
|
||||
<code>UIOP</code> provides hooks
|
||||
to call functions before an image is dumped,
|
||||
from which to reset or <code>makunbound</code> relevant variables.
|
||||
<code>UIOP</code> provides hooks
|
||||
to call functions before an image is dumped,
|
||||
from which to reset or <code>makunbound</code> relevant variables.
|
||||
</p>
|
||||
|
||||
</BODY>
|
||||
|
@ -3754,7 +3764,8 @@ Robert Brown
|
|||
<p>
|
||||
That is why any function specified in a <code>SATISFIES</code> clause
|
||||
MUST accept objects of any type as argument to the function,
|
||||
and MUST be defined within an <code>EVAL-WHEN</code>.
|
||||
and MUST be defined within an <code>EVAL-WHEN</code>
|
||||
(as well as any variable it uses or function it calls):
|
||||
</p>
|
||||
<BAD_CODE_SNIPPET>
|
||||
(defun prime-number-p (n) ; Doubly bad!
|
||||
|
@ -3829,7 +3840,7 @@ Robert Brown
|
|||
</small>
|
||||
|
||||
<p align="right">
|
||||
Revision 1.22
|
||||
Revision 1.23
|
||||
</p>
|
||||
|
||||
|
||||
|
|
232
objcguide.xml
232
objcguide.xml
|
@ -4,7 +4,7 @@
|
|||
|
||||
<p align="right">
|
||||
|
||||
Revision 2.56
|
||||
Revision 2.59
|
||||
</p>
|
||||
|
||||
|
||||
|
@ -132,24 +132,20 @@ Revision 2.56
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
// A sample class demonstrating good Objective-C style. All interfaces,
|
||||
// categories, and protocols (read: all top-level declarations in a header)
|
||||
// MUST be commented. Comments must also be adjacent to the object they're
|
||||
// documenting.
|
||||
// categories, and protocols (read: all non-trivial top-level declarations
|
||||
// in a header) MUST be commented. Comments must also be adjacent to the
|
||||
// object they're documenting.
|
||||
//
|
||||
// (no blank line between this comment and the interface)
|
||||
@interface Foo : NSObject {
|
||||
@private
|
||||
NSString *_bar;
|
||||
NSString *_bam;
|
||||
}
|
||||
@interface Foo : NSObject
|
||||
|
||||
// Returns an autoreleased instance of Foo. See -initWithBar: for details
|
||||
// about |bar|.
|
||||
+ (id)fooWithBar:(NSString *)bar;
|
||||
+ (instancetype)fooWithBar:(NSString *)bar;
|
||||
|
||||
// Designated initializer. |bar| is a thing that represents a thing that
|
||||
// does a thing.
|
||||
- (id)initWithBar:(NSString *)bar;
|
||||
- (instancetype)initWithBar:(NSString *)bar;
|
||||
|
||||
// Gets and sets |_bar|.
|
||||
- (NSString *)bar;
|
||||
|
@ -173,18 +169,21 @@ Revision 2.56
|
|||
#import "Foo.h"
|
||||
|
||||
|
||||
@implementation Foo
|
||||
@implementation Foo {
|
||||
NSString *_bar;
|
||||
NSString *_foo;
|
||||
}
|
||||
|
||||
+ (id)fooWithBar:(NSString *)bar {
|
||||
+ (instancetype)fooWithBar:(NSString *)bar {
|
||||
return [[[self alloc] initWithBar:bar] autorelease];
|
||||
}
|
||||
|
||||
// Must always override super's designated initializer.
|
||||
- (id)init {
|
||||
- (instancetype)init {
|
||||
return [self initWithBar:nil];
|
||||
}
|
||||
|
||||
- (id)initWithBar:(NSString *)bar {
|
||||
- (instancetype)initWithBar:(NSString *)bar {
|
||||
if ((self = [super init])) {
|
||||
_bar = [bar copy];
|
||||
_bam = [[NSString alloc] initWithFormat:@"hi %d", 3];
|
||||
|
@ -246,29 +245,14 @@ Revision 2.56
|
|||
|
||||
<STYLEPOINT title="Line Length">
|
||||
<SUMMARY>
|
||||
Each line of text in your code should try to be at most 80 characters
|
||||
long.
|
||||
The maximum line length for Objective-C and Objective-C++ files is 100
|
||||
columns. Projects may opt to use an 80 column limit for consistency with
|
||||
the C++ style guide.
|
||||
</SUMMARY>
|
||||
<BODY>
|
||||
<p>
|
||||
Strive to keep your code within 80 columns. We realize that Objective C
|
||||
is a verbose language and in some cases it may be more readable to
|
||||
extend slightly beyond 80 columns, but this should definitely be the
|
||||
exception and not commonplace.
|
||||
</p>
|
||||
<p>
|
||||
If a reviewer asks that you reformat a line because they feel it can be
|
||||
fit in 80 columns and still be readable, you should do so.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
We recognize that this rule is controversial, but so much existing
|
||||
code already adheres to it, and we feel that consistency is
|
||||
important.
|
||||
</p>
|
||||
<p>
|
||||
You can make violations easier to spot in Xcode by going to <i>Xcode
|
||||
> Preferences > Text Editing > Show page guide</i>.
|
||||
You can make violations easier to spot by enabling <i>Preferences >
|
||||
Text Editing > Page guide at column: 100</i> in Xcode.
|
||||
</p>
|
||||
</BODY>
|
||||
</STYLEPOINT>
|
||||
|
@ -445,9 +429,7 @@ Revision 2.56
|
|||
|
||||
<STYLEPOINT title="Blocks">
|
||||
<SUMMARY>
|
||||
Blocks are preferred to the target-selector pattern when creating
|
||||
callbacks, as it makes code easier to read. Code inside blocks should be
|
||||
indented four spaces.
|
||||
Code inside blocks should be indented four spaces.
|
||||
</SUMMARY>
|
||||
<BODY>
|
||||
<p>
|
||||
|
@ -743,7 +725,7 @@ Revision 2.56
|
|||
- (void)respondToSomething:(id)something {
|
||||
// bridge from Cocoa through our C++ backend
|
||||
_instanceVar = _backEndObject->DoSomethingPlatformSpecific();
|
||||
NSString* tempString = [NSString stringWithInt:_instanceVar];
|
||||
NSString* tempString = [NSString stringWithFormat:@"%d", _instanceVar];
|
||||
NSLog(@"%@", tempString);
|
||||
}
|
||||
@end
|
||||
|
@ -751,7 +733,7 @@ Revision 2.56
|
|||
// The platform-specific implementation of the C++ class, using
|
||||
// C++ naming.
|
||||
int CrossPlatformAPI::DoSomethingPlatformSpecific() {
|
||||
NSString* temp_string = [NSString stringWithInt:an_instance_var_];
|
||||
NSString* temp_string = [NSString stringWithFormat:@"%d", an_instance_var_];
|
||||
NSLog(@"%@", temp_string);
|
||||
return [temp_string intValue];
|
||||
}
|
||||
|
@ -766,11 +748,10 @@ Revision 2.56
|
|||
</SUMMARY>
|
||||
<BODY>
|
||||
<p>
|
||||
In <em>application-level</em> code, prefixes on class names should
|
||||
generally be avoided. Having every single class with same prefix
|
||||
impairs readability for no benefit. When designing code to be shared
|
||||
across multiple applications, prefixes are acceptable and recommended
|
||||
(e.g. <code>GTMSendMessage</code>).
|
||||
When designing code to be shared across multiple applications,
|
||||
prefixes are acceptable and recommended (e.g. <code>GTMSendMessage</code>).
|
||||
Prefixes are also recommended for classes of large applications that
|
||||
depend on external libraries.
|
||||
</p>
|
||||
|
||||
</BODY>
|
||||
|
@ -1038,31 +1019,25 @@ Revision 2.56
|
|||
<p>
|
||||
Where instance variables are pointers to Core Foundation, C++, and
|
||||
other non-Objective-C objects, they should always be declared with
|
||||
the __strong or __weak type modifiers to indicate which pointers are
|
||||
and are not retained. Core Foundation and other non-Objective-C object
|
||||
pointers require explicit memory management, even when building for
|
||||
automatic reference counting or garbage collection. When the __weak
|
||||
type modifier is not allowed (e.g. C++ member variables when compiled
|
||||
under clang), a comment should be used instead.
|
||||
</p>
|
||||
<p>
|
||||
Be mindful that support for automatic C++ objects encapsulated in
|
||||
Objective-C objects is disabled by default, as described <a href="http://chanson.livejournal.com/154253.html">
|
||||
here</a>.
|
||||
<code>strong</code> and <code>weak</code> comments to indicate which
|
||||
pointers are and are not retained. Core Foundation and other
|
||||
non-Objective-C object pointers require explicit memory management,
|
||||
even when building for automatic reference counting or garbage
|
||||
collection.
|
||||
</p>
|
||||
<p>
|
||||
Examples of strong and weak declarations:
|
||||
<CODE_SNIPPET>
|
||||
@interface MyDelegate : NSObject {
|
||||
@private
|
||||
IBOutlet NSButton *_okButton; // normal NSControl; implicitly weak on Mac only
|
||||
IBOutlet NSButton *_okButton; // Normal NSControl; implicitly weak on Mac only
|
||||
|
||||
AnObjcObject* _doohickey; // my doohickey
|
||||
__weak MyObjcParent *_parent; // so we can send msgs back (owns me)
|
||||
AnObjcObject* _doohickey; // My doohickey
|
||||
__weak MyObjcParent *_parent; // So we can send msgs back (owns me)
|
||||
|
||||
// non-NSObject pointers...
|
||||
__strong CWackyCPPClass *_wacky; // some cross-platform object
|
||||
__strong CFDictionaryRef *_dict;
|
||||
CWackyCPPClass *_wacky; // Strong, some cross-platform object
|
||||
CFDictionaryRef *_dict; // Strong
|
||||
}
|
||||
@property(strong, nonatomic) NSString *doohickey;
|
||||
@property(weak, nonatomic) NSString *parent;
|
||||
|
@ -1085,8 +1060,9 @@ Revision 2.56
|
|||
|
||||
<STYLEPOINT title="Instance Variables In Headers Should Be @private">
|
||||
<SUMMARY>
|
||||
Instance variables should be marked <code>@private</code> when they are
|
||||
declared in a header file.
|
||||
Instance variables should typically be declared in implementation files
|
||||
or auto-synthesized by properties. When ivars are declared in a header
|
||||
file, they should be marked <code>@private</code>.
|
||||
</SUMMARY>
|
||||
<BODY>
|
||||
<CODE_SNIPPET>
|
||||
|
@ -1094,9 +1070,6 @@ Revision 2.56
|
|||
@private
|
||||
id _myInstanceVariable;
|
||||
}
|
||||
// public accessors, setter takes ownership
|
||||
- (id)myInstanceVariable;
|
||||
- (void)setMyInstanceVariable:(id)theVar;
|
||||
@end
|
||||
</CODE_SNIPPET>
|
||||
</BODY>
|
||||
|
@ -1139,11 +1112,16 @@ Revision 2.56
|
|||
<code>@implementation</code>.
|
||||
</SUMMARY>
|
||||
<BODY>
|
||||
This commonly applies (but is not limited) to the <code>init...</code>,
|
||||
<code>copyWithZone:</code>, and <code>dealloc</code> methods.
|
||||
<code>init...</code> methods should be grouped together, followed by
|
||||
the <code>copyWithZone:</code> method, and finally the
|
||||
<code>dealloc</code> method.
|
||||
<p>
|
||||
This commonly applies (but is not limited) to the <code>init...</code>,
|
||||
<code>copyWithZone:</code>, and <code>dealloc</code> methods.
|
||||
<code>init...</code> methods should be grouped together, followed by
|
||||
other <code>NSObject</code> methods.
|
||||
</p>
|
||||
<p>
|
||||
Convenience class methods for creating instances may precede the
|
||||
<code>NSObject</code> methods.
|
||||
</p>
|
||||
</BODY>
|
||||
</STYLEPOINT>
|
||||
|
||||
|
@ -1201,7 +1179,7 @@ Revision 2.56
|
|||
- (NSString *)doSomethingWithDelegate; // Declare private method
|
||||
@end
|
||||
|
||||
@implementation GTMFoo(PrivateDelegateHandling)
|
||||
@implementation GTMFoo (PrivateDelegateHandling)
|
||||
...
|
||||
- (NSString *)doSomethingWithDelegate {
|
||||
// Implement this method
|
||||
|
@ -1209,14 +1187,6 @@ Revision 2.56
|
|||
...
|
||||
@end
|
||||
</CODE_SNIPPET>
|
||||
<p>
|
||||
Before Objective-C 2.0, if you declare a method in the private
|
||||
<code>@interface</code>, but forget to implement it in the main
|
||||
<code>@implementation</code>, the compiler will <i>not</i> object.
|
||||
(This is because you don't implement these private methods in a
|
||||
separate category.) The solution is to put the functions within
|
||||
an <code>@implementation</code> that specifies the category.
|
||||
</p>
|
||||
<p>
|
||||
If you are using Objective-C 2.0, you should instead declare your
|
||||
private category using a <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articles/chapter_4_section_5.html#">class
|
||||
|
@ -1387,7 +1357,7 @@ Revision 2.56
|
|||
accessors.
|
||||
</p>
|
||||
<CODE_SNIPPET>
|
||||
- (id)init {
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_bar = [[NSMutableString alloc] init]; // good
|
||||
|
@ -1401,7 +1371,7 @@ Revision 2.56
|
|||
}
|
||||
</CODE_SNIPPET>
|
||||
<BAD_CODE_SNIPPET>
|
||||
- (id)init {
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.bar = [NSMutableString string]; // avoid
|
||||
|
@ -1475,62 +1445,6 @@ Revision 2.56
|
|||
you do use them please document exactly which methods you expect to
|
||||
throw.
|
||||
</p>
|
||||
<p>
|
||||
Do not use the <code>NS_DURING</code>, <code>NS_HANDLER</code>,
|
||||
<code>NS_ENDHANDLER</code>, <code>NS_VALUERETURN</code> and
|
||||
<code>NS_VOIDRETURN</code> macros unless you are writing code that
|
||||
needs to run on Mac OS X 10.2 or before.
|
||||
</p>
|
||||
<p>
|
||||
Also be aware when writing Objective-C++ code that stack based objects
|
||||
are <b>not</b> cleaned up when you throw an Objective-C exception.
|
||||
Example:
|
||||
</p>
|
||||
<CODE_SNIPPET>
|
||||
class exceptiontest {
|
||||
public:
|
||||
exceptiontest() { NSLog(@"Created"); }
|
||||
~exceptiontest() { NSLog(@"Destroyed"); }
|
||||
};
|
||||
|
||||
void foo() {
|
||||
exceptiontest a;
|
||||
NSException *exception = [NSException exceptionWithName:@"foo"
|
||||
reason:@"bar"
|
||||
userInfo:nil];
|
||||
@throw exception;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
GMAutoreleasePool pool;
|
||||
@try {
|
||||
foo();
|
||||
}
|
||||
@catch(NSException *ex) {
|
||||
NSLog(@"exception raised");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
</CODE_SNIPPET>
|
||||
<p>
|
||||
will give you:
|
||||
</p>
|
||||
<CODE_SNIPPET>
|
||||
2006-09-28 12:34:29.244 exceptiontest[23661] Created
|
||||
2006-09-28 12:34:29.244 exceptiontest[23661] exception raised
|
||||
</CODE_SNIPPET>
|
||||
<p>
|
||||
Note that the destructor for <i>a</i> never got called. This is a
|
||||
major concern for stack based smartptrs such as
|
||||
<code>shared_ptr</code> and <code>linked_ptr</code>, as well as any
|
||||
STL objects that you may want to use. Therefore it pains us to say
|
||||
that if you must use exceptions in your Objective-C++ code, use C++
|
||||
exceptions whenever possible. You should never re-throw an Objective-C
|
||||
exception, nor are stack based C++ objects (such as
|
||||
<code>std::string</code>, <code>std::vector</code> etc.) allowed in
|
||||
the body of any <code>@try</code>, <code>@catch</code>, or
|
||||
<code>@finally</code> blocks.
|
||||
</p>
|
||||
</BODY>
|
||||
</STYLEPOINT>
|
||||
|
||||
|
@ -1541,19 +1455,24 @@ Revision 2.56
|
|||
</SUMMARY>
|
||||
<BODY>
|
||||
<p>
|
||||
Use <code>nil</code> checks for logic flow of the application, not for
|
||||
crash prevention. Sending a message to a <code>nil</code> object is
|
||||
handled by the Objective-C runtime. If the method has no return
|
||||
result, you're good to go. However if there is one, there may be
|
||||
differences based on runtime architecture, return size, and OS X
|
||||
version (see <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocObjectsClasses.html#//apple_ref/doc/uid/TP30001163-CH11-SW7">Apple's
|
||||
documentation</a> for specifics).
|
||||
Use <code>nil</code> pointer checks for logic flow of the application,
|
||||
not for preventing crashes when sending messages. With current compilers
|
||||
(<a href="http://www.sealiesoftware.com/blog/archive/2012/2/29/objc_explain_return_value_of_message_to_nil.html">
|
||||
as of LLVM 3.0/Xcode 4.2</a>), sending a message to <code>nil</code>
|
||||
reliably returns nil as a pointer, zero as an integer or floating-point
|
||||
value, structs initialized to 0, and <code>_Complex</code> values equal
|
||||
to {0, 0}.
|
||||
</p>
|
||||
<p>
|
||||
Note that this is very different from checking C/C++ pointers against
|
||||
<code>NULL</code>, which the runtime does not handle and will cause
|
||||
your application to crash. You still need to make sure you do not
|
||||
dereference a <code>NULL</code> pointer.
|
||||
Note that this applies to <code>nil</code> as a message target, not as
|
||||
a parameter value. Individual methods may or may not safely handle
|
||||
<code>nil</code> parameter values.
|
||||
</p>
|
||||
<p>
|
||||
Note too that this is distinct from checking C/C++ pointers and block
|
||||
pointers against <code>NULL</code>, which the runtime does not handle
|
||||
and will cause your application to crash. You still need to make sure
|
||||
you do not dereference a <code>NULL</code> pointer.
|
||||
</p>
|
||||
</BODY>
|
||||
</STYLEPOINT>
|
||||
|
@ -1677,7 +1596,7 @@ Revision 2.56
|
|||
@implementation MyClass
|
||||
@synthesize name = _name;
|
||||
|
||||
- (id)init {
|
||||
- (instancetype)init {
|
||||
...
|
||||
}
|
||||
@end
|
||||
|
@ -1867,11 +1786,12 @@ Revision 2.56
|
|||
|
||||
<STYLEPOINT title="Delegate Pattern">
|
||||
<SUMMARY>
|
||||
Delegate objects should not be retained.
|
||||
Delegate objects should not be retained when doing so would create
|
||||
a retain cycle.
|
||||
</SUMMARY>
|
||||
<BODY>
|
||||
<p>
|
||||
A class that implements the delegate pattern should:
|
||||
A class that implements the delegate pattern should typically:
|
||||
<ol>
|
||||
<li>
|
||||
Have an instance variable named <var>_delegate</var> to reference
|
||||
|
@ -1882,7 +1802,9 @@ Revision 2.56
|
|||
and <code>setDelegate:</code>.
|
||||
</li>
|
||||
<li>
|
||||
The <var>_delegate</var> object should <b>not</b> be retained.
|
||||
The <var>_delegate</var> object should be weak if the class
|
||||
is typically retained by its delegate, such that a strong delegate
|
||||
would create a retain cycle.
|
||||
</li>
|
||||
</ol>
|
||||
</p>
|
||||
|
@ -1915,8 +1837,6 @@ Revision 2.56
|
|||
<li>
|
||||
Define callback APIs with <code>@protocol</code>, using
|
||||
<code>@optional</code> if not all the methods are required.
|
||||
(Exception: when using Objective-C 1.0, <code>@optional</code> isn't
|
||||
available, so use a category to define an "informal protocol".)
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
@ -1951,7 +1871,7 @@ Revision 2.56
|
|||
<HR/>
|
||||
|
||||
<p align="right">
|
||||
Revision 2.56
|
||||
Revision 2.59
|
||||
</p>
|
||||
|
||||
|
||||
|
|
154
pyguide.html
154
pyguide.html
|
@ -136,7 +136,7 @@
|
|||
<H1>Google Python Style Guide</H1>
|
||||
<p align="right">
|
||||
|
||||
Revision 2.54
|
||||
Revision 2.59
|
||||
</p>
|
||||
|
||||
<address>
|
||||
|
@ -165,7 +165,7 @@
|
|||
<TR valign="top" class="">
|
||||
<TD><DIV class="toc_category"><A href="#Python_Language_Rules">Python Language Rules</A></DIV></TD>
|
||||
<TD><DIV class="toc_stylepoint">
|
||||
<SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#pychecker">pychecker</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Imports">Imports</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Packages">Packages</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Exceptions">Exceptions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Global_variables">Global variables</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Nested/Local/Inner_Classes_and_Functions">Nested/Local/Inner Classes and Functions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#List_Comprehensions">List Comprehensions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Default_Iterators_and_Operators">Default Iterators and Operators</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Generators">Generators</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Lambda_Functions">Lambda Functions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Conditional_Expressions">Conditional Expressions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Default_Argument_Values">Default Argument Values</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Properties">Properties</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#True/False_evaluations">True/False evaluations</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Deprecated_Language_Features">Deprecated Language Features</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Lexical_Scoping">Lexical Scoping</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Function_and_Method_Decorators">Function and Method Decorators</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Threading">Threading</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Power_Features">Power Features</A></SPAN> </DIV></TD>
|
||||
<SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Lint">Lint</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Imports">Imports</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Packages">Packages</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Exceptions">Exceptions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Global_variables">Global variables</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Nested/Local/Inner_Classes_and_Functions">Nested/Local/Inner Classes and Functions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#List_Comprehensions">List Comprehensions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Default_Iterators_and_Operators">Default Iterators and Operators</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Generators">Generators</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Lambda_Functions">Lambda Functions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Conditional_Expressions">Conditional Expressions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Default_Argument_Values">Default Argument Values</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Properties">Properties</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#True/False_evaluations">True/False evaluations</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Deprecated_Language_Features">Deprecated Language Features</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Lexical_Scoping">Lexical Scoping</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Function_and_Method_Decorators">Function and Method Decorators</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Threading">Threading</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Power_Features">Power Features</A></SPAN> </DIV></TD>
|
||||
</TR>
|
||||
<TR valign="top" class="">
|
||||
<TD><DIV class="toc_category"><A href="#Python_Style_Rules">Python Style Rules</A></DIV></TD>
|
||||
|
@ -214,58 +214,77 @@
|
|||
|
||||
<DIV class="">
|
||||
<H2 name="Python_Language_Rules" id="Python_Language_Rules">Python Language Rules</H2>
|
||||
|
||||
<DIV class="">
|
||||
<H3><A name="pychecker" id="pychecker">pychecker</A></H3>
|
||||
<SPAN class="link_button" id="link-pychecker__button" name="link-pychecker__button"><A href="?showone=pychecker#pychecker">
|
||||
<DIV class="">
|
||||
<H3><A name="Lint" id="Lint">Lint</A></H3>
|
||||
<SPAN class="link_button" id="link-Lint__button" name="link-Lint__button"><A href="?showone=Lint#Lint">
|
||||
link
|
||||
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('pychecker')" name="pychecker__button" id="pychecker__button">▶</SPAN>
|
||||
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Lint')" name="Lint__button" id="Lint__button">▶</SPAN>
|
||||
<DIV style="display:inline;" class="">
|
||||
Run <code>pychecker</code> over your code.
|
||||
Run <code>pylint</code> over your code.
|
||||
</DIV>
|
||||
<DIV class=""><DIV class="stylepoint_body" name="pychecker__body" id="pychecker__body" style="display: none">
|
||||
<DIV class=""><DIV class="stylepoint_body" name="Lint__body" id="Lint__body" style="display: none">
|
||||
<P class="">
|
||||
<SPAN class="stylepoint_section">Definition: </SPAN>
|
||||
PyChecker is a tool for finding bugs in Python source code. It finds
|
||||
pylint
|
||||
is a tool for finding bugs and style problems in Python source
|
||||
code. It finds
|
||||
problems that are typically caught by a compiler for less dynamic
|
||||
languages like C and C++. It is similar to lint. Because of the
|
||||
languages like C and C++.
|
||||
|
||||
Because of the
|
||||
dynamic nature of Python, some warnings may be incorrect; however,
|
||||
spurious warnings should be fairly infrequent.
|
||||
</P>
|
||||
<P class="">
|
||||
<SPAN class="stylepoint_section">Pros: </SPAN>
|
||||
Catches easy-to-miss errors like typos, use-vars-before-assignment, etc.
|
||||
Catches easy-to-miss errors like typos, using-vars-before-assignment, etc.
|
||||
</P>
|
||||
<P class="">
|
||||
<SPAN class="stylepoint_section">Cons: </SPAN>
|
||||
<code>pychecker</code> isn't perfect. To take
|
||||
advantage of it, we'll need to sometimes: a) Write around it b)
|
||||
Suppress its warnings c) Improve it or d) Ignore it.
|
||||
<code>pylint</code>
|
||||
isn't perfect. To take advantage of it, we'll need to sometimes:
|
||||
a) Write around it b) Suppress its warnings or c) Improve it.
|
||||
</P>
|
||||
<P class="">
|
||||
<SPAN class="stylepoint_section">Decision: </SPAN>
|
||||
Make sure you run <code>pychecker</code> on your code.
|
||||
Make sure you run <code>pylint</code> on your code.
|
||||
Suppress warnings if they are inappropriate so that other issues are
|
||||
not hidden.
|
||||
</P>
|
||||
|
||||
<p>
|
||||
For information on how to run <code>pychecker</code>, see the
|
||||
<a HREF="http://pychecker.sourceforge.net">pychecker
|
||||
homepage</a>
|
||||
</p>
|
||||
<p>
|
||||
To suppress warnings, you can set a module-level variable named
|
||||
<code>__pychecker__</code> to suppress appropriate warnings.
|
||||
For example:
|
||||
To suppress warnings, you can set a line-level comment:
|
||||
</p>
|
||||
|
||||
<DIV class=""><PRE>
|
||||
<span class="external"></span>__pychecker__ = 'no-callinit no-classattr'</PRE></DIV>
|
||||
<span class="external"></span>dict = 'something awful' # Bad Idea... pylint: disable=redefined-builtin</PRE></DIV>
|
||||
<p>
|
||||
Suppressing in this way has the advantage that we can easily search
|
||||
for suppressions and revisit them.
|
||||
pylint
|
||||
warnings are each identified by a alphanumeric code
|
||||
(<code>C0112</code>) and a symbolic name
|
||||
(<code>empty-docstring</code>). Prefer the symbolic
|
||||
names in new code or when updating existing code.
|
||||
|
||||
</p>
|
||||
<p>
|
||||
You can get a list of pychecker warnings by doing
|
||||
<code>pychecker --help</code>.
|
||||
If the reason for the suppression is not clear from the symbolic name,
|
||||
add an explanation.
|
||||
</p>
|
||||
<p>
|
||||
Suppressing in this way has the advantage that we can easily search
|
||||
for suppressions and revisit them.
|
||||
</p>
|
||||
<p>
|
||||
You can get a list of
|
||||
pylint
|
||||
warnings by doing
|
||||
<code>pylint --list-msgs</code>.
|
||||
To get more information on a particular message, use
|
||||
<code>pylint --help-msg=C6409</code>.
|
||||
</p>
|
||||
<p>
|
||||
Prefer <code>pylint: disable</code> to the deprecated older form
|
||||
<code>pylint: disable-msg</code>.
|
||||
</p>
|
||||
<p>
|
||||
Unused argument warnings can be suppressed by using `_' as the
|
||||
|
@ -280,11 +299,6 @@
|
|||
<span class="external"> </span>return a
|
||||
<span class="external"></span>
|
||||
</PRE></DIV>
|
||||
<p>
|
||||
Ideally, pychecker would be extended to ensure that such `unused
|
||||
declarations' were true.
|
||||
</p>
|
||||
|
||||
</DIV></DIV>
|
||||
</DIV>
|
||||
<DIV class="">
|
||||
|
@ -358,7 +372,6 @@
|
|||
<P class="">
|
||||
<SPAN class="stylepoint_section">Decision: </SPAN>
|
||||
All new code should import each module by its full package name.
|
||||
|
||||
</P>
|
||||
<p>
|
||||
Imports should be as follows:
|
||||
|
@ -784,6 +797,10 @@ from sound.effects import echo
|
|||
<span class="external"> </span>if b is None:
|
||||
<span class="external"> </span>b = []</PRE></DIV>
|
||||
<DIV class=""><PRE class="badcode">No: <span class="external"></span>def foo(a, b=[]):
|
||||
<span class="external"> </span>...
|
||||
No: <span class="external"></span>def foo(a, b=time.time()): # The time the module was loaded???
|
||||
<span class="external"> </span>...
|
||||
No: <span class="external"></span>def foo(a, b=FLAGS.my_thing): # sys.argv has not yet been parsed...
|
||||
<span class="external"> </span>...</PRE></DIV>
|
||||
</P>
|
||||
</DIV></DIV>
|
||||
|
@ -1134,7 +1151,7 @@ from sound.effects import echo
|
|||
Avoid external dependencies in the decorator itself (e.g. don't rely on
|
||||
files, sockets, database connections, etc.), since they might not be
|
||||
available when the decorator runs (at import time, perhaps from
|
||||
<code>pychecker</code> or other tools). A decorator that is
|
||||
<code>pydoc</code> or other tools). A decorator that is
|
||||
called with valid parameters should (as much as possible) be guaranteed
|
||||
to succeed in all cases.
|
||||
</p>
|
||||
|
@ -1347,10 +1364,24 @@ from sound.effects import echo
|
|||
foo = long_function_name(var_one, var_two,
|
||||
var_three, var_four)
|
||||
|
||||
# Aligned with opening delimiter in a dictionary
|
||||
foo = {
|
||||
long_dictionary_key: value1 +
|
||||
value2,
|
||||
...
|
||||
}
|
||||
|
||||
# 4-space hanging indent; nothing on first line
|
||||
foo = long_function_name(
|
||||
var_one, var_two, var_three,
|
||||
var_four)</PRE></DIV>
|
||||
var_four)
|
||||
|
||||
# 4-space hanging indent in a dictionary
|
||||
foo = {
|
||||
long_dictionary_key:
|
||||
long_dictionary_value,
|
||||
...
|
||||
}</PRE></DIV>
|
||||
<DIV class=""><PRE class="badcode">No: <span class="external"></span># Stuff on first line forbidden
|
||||
<span class="external"></span>foo = long_function_name(var_one, var_two,
|
||||
<span class="external"></span> var_three, var_four)
|
||||
|
@ -1358,7 +1389,14 @@ from sound.effects import echo
|
|||
<span class="external"></span># 2-space hanging indent forbidden
|
||||
<span class="external"></span>foo = long_function_name(
|
||||
<span class="external"></span> var_one, var_two, var_three,
|
||||
<span class="external"></span> var_four)</PRE></DIV>
|
||||
<span class="external"></span> var_four)
|
||||
|
||||
<span class="external"></span># No hanging indent in a dictionary
|
||||
<span class="external"></span>foo = {
|
||||
<span class="external"></span> long_dictionary_key:
|
||||
<span class="external"> </span>long_dictionary_value,
|
||||
<span class="external"> </span>...
|
||||
<span class="external"></span>}</PRE></DIV>
|
||||
</DIV></DIV>
|
||||
</DIV>
|
||||
<DIV class="">
|
||||
|
@ -1502,9 +1540,10 @@ from sound.effects import echo
|
|||
module, class or function. These strings can be extracted
|
||||
automatically through the <code>__doc__</code> member of the
|
||||
object and are used by <code>pydoc</code>. (Try running
|
||||
<code>pydoc</code> on your module to see how it looks.) Our
|
||||
convention for doc strings is to use the three double-quote
|
||||
format for strings. A doc string should be organized as a
|
||||
<code>pydoc</code> on your module to see how it looks.) We
|
||||
always use the three double-quote <code>"""</code> format for doc strings
|
||||
(per <a href="http://www.python.org/dev/peps/pep-0257/">PEP 257</a>).
|
||||
A doc string should be organized as a
|
||||
summary line (one physical line) terminated by a period,
|
||||
question mark, or exclamation point, followed by a blank line,
|
||||
followed by the rest of the doc string starting at the same
|
||||
|
@ -1784,8 +1823,29 @@ from sound.effects import echo
|
|||
<span class="external"></span>employee_table += '</table>'</PRE></DIV>
|
||||
|
||||
<p>
|
||||
Use <code>"""</code> for multi-line strings rather than
|
||||
<code>'''</code>. Note, however, that it is often cleaner to
|
||||
Be consistent with your choice of string quote character within a file.
|
||||
Pick <code>'</code> or <code>"</code> and stick with it.
|
||||
It is okay to use the other quote character on a string to avoid the
|
||||
need to <code>\</code> escape within the string.
|
||||
GPyLint enforces this.
|
||||
</p>
|
||||
|
||||
<DIV class=""><PRE>Ye<span class="external"></span>s:
|
||||
<span class="external"></span>Python('Why are you hiding your eyes?')
|
||||
<span class="external"></span>Gollum("I'm scared of lint errors.")
|
||||
<span class="external"></span>Narrator('"Good!" thought a happy Python reviewer.')</PRE></DIV>
|
||||
<DIV class=""><PRE class="badcode">No<span class="external"></span>:
|
||||
<span class="external"></span>Python("Why are you hiding your eyes?")
|
||||
<span class="external"></span>Gollum('The lint. It burns. It burns us.')
|
||||
<span class="external"></span>Gollum("Always the great lint. Watching. Watching.")</PRE></DIV>
|
||||
|
||||
<p>
|
||||
Prefer <code>"""</code> for multi-line strings rather than
|
||||
<code>'''</code>. Projects may choose to use <code>'''</code> for
|
||||
all non-docstring multi-line strings if and only if they also use
|
||||
<code>'</code> for regular strings.
|
||||
Doc strings must use <code>"""</code> regardless.
|
||||
Note that it is often cleaner to
|
||||
use implicit line joining since multi-line strings do
|
||||
not flow with the indentation of the rest of the program:
|
||||
</p>
|
||||
|
@ -2174,7 +2234,7 @@ Don'<span class="external"></span>t do this.
|
|||
<DIV class=""><DIV class="stylepoint_body" name="Main__body" id="Main__body" style="display: none">
|
||||
<p>
|
||||
In Python,
|
||||
<code>pychecker</code>, <code>pydoc</code>, and unit tests
|
||||
<code>pydoc</code> as well as unit tests
|
||||
require modules to be importable. Your code should always check
|
||||
<code>if __name__ == '__main__'</code> before executing your
|
||||
main program so that the main program is not executed when the
|
||||
|
@ -2201,7 +2261,7 @@ Don'<span class="external"></span>t do this.
|
|||
All code at the top level will be executed when the module is
|
||||
imported. Be careful not to call functions, create objects, or
|
||||
perform other operations that should not be executed when the
|
||||
file is being <code>pycheck</code>ed or <code>pydoc</code>ed.
|
||||
file is being <code>pydoc</code>ed.
|
||||
</p>
|
||||
</DIV></DIV>
|
||||
</DIV>
|
||||
|
@ -2233,7 +2293,7 @@ Don'<span class="external"></span>t do this.
|
|||
|
||||
|
||||
<p align="right">
|
||||
Revision 2.54
|
||||
Revision 2.59
|
||||
</p>
|
||||
|
||||
|
||||
|
@ -2241,9 +2301,11 @@ Revision 2.54
|
|||
Amit Patel<br>
|
||||
Antoine Picard<br>
|
||||
Eugene Jhong<br>
|
||||
Gregory P. Smith<br>
|
||||
Jeremy Hylton<br>
|
||||
Matt Smart<br>
|
||||
Mike Shields<br>
|
||||
Shane Liebling<br>
|
||||
</address>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
|
75
shell.xml
75
shell.xml
|
@ -4,7 +4,7 @@
|
|||
|
||||
<p align="right">
|
||||
|
||||
Revision 1.25
|
||||
Revision 1.26
|
||||
</p>
|
||||
|
||||
|
||||
|
@ -393,6 +393,73 @@ Revision 1.25
|
|||
</BODY>
|
||||
</STYLEPOINT>
|
||||
|
||||
<STYLEPOINT title="Case statement">
|
||||
<SUMMARY>
|
||||
<ul>
|
||||
<li>
|
||||
Indent alternatives by 2 spaces.
|
||||
</li>
|
||||
<li>
|
||||
A one-line alternative needs a space after the close parenthesis of
|
||||
the pattern and before the <code>;;</code>.
|
||||
</li>
|
||||
<li>
|
||||
Long or multi-command alternatives should be split over multiple
|
||||
lines with the pattern, actions, and <code>;;</code> on separate
|
||||
lines.
|
||||
</li>
|
||||
</ul>
|
||||
</SUMMARY>
|
||||
<BODY>
|
||||
<p>
|
||||
The matching expressions are indented one level from the 'case' and
|
||||
'esac'. Multiline actions are indented another level. In general,
|
||||
there is no need to quote match expressions. Pattern expressions
|
||||
should not be preceded by an open parenthesis. Avoid the
|
||||
<code>;&</code> and <code>;;&</code> notations.
|
||||
</p>
|
||||
<CODE_SNIPPET>
|
||||
case "${expression}" in
|
||||
a)
|
||||
variable="..."
|
||||
some_command "${variable}" "${other_expr}" ...
|
||||
;;
|
||||
absolute)
|
||||
actions="relative"
|
||||
another_command "${actions}" "${other_expr}" ...
|
||||
;;
|
||||
*)
|
||||
error "Unexpected expression '${expression}'"
|
||||
;;
|
||||
esac
|
||||
</CODE_SNIPPET>
|
||||
<p>
|
||||
Simple commands may be put on the same line as the pattern <i>and</i>
|
||||
<code>;;</code> as long as the expression remains readable. This is
|
||||
often appropriate for single-letter option processing. When the
|
||||
actions don't fit on a single line, put the pattern on a line on its
|
||||
own, then the actions, then <code>;;</code> also on a line of its own.
|
||||
When on the same line as the actions, use a space after the close
|
||||
parenthesis of the pattern and another before the <code>;;</code>.
|
||||
</p>
|
||||
<CODE_SNIPPET>
|
||||
verbose='false'
|
||||
aflag=''
|
||||
bflag=''
|
||||
files=''
|
||||
while getopts 'abf:v' flag; do
|
||||
case "${flag}" in
|
||||
a) aflag='true' ;;
|
||||
b) bflag='true' ;;
|
||||
f) files="${OPTARG}" ;;
|
||||
v) verbose='true' ;;
|
||||
*) error "Unexpected option ${flag}" ;;
|
||||
esac
|
||||
done
|
||||
</CODE_SNIPPET>
|
||||
</BODY>
|
||||
</STYLEPOINT>
|
||||
|
||||
<STYLEPOINT title="Variable expansion">
|
||||
<SUMMARY>
|
||||
In order of precedence: Stay consistent with what you find;
|
||||
|
@ -856,9 +923,7 @@ Revision 1.25
|
|||
VERBOSE='false'
|
||||
while getopts 'v' flag; do
|
||||
case "${flag}" in
|
||||
'v')
|
||||
VERBOSE='true'
|
||||
;;
|
||||
v) VERBOSE='true' ;;
|
||||
esac
|
||||
done
|
||||
readonly VERBOSE
|
||||
|
@ -1081,7 +1146,7 @@ Revision 1.25
|
|||
</CATEGORY>
|
||||
|
||||
<p align="right">
|
||||
Revision 1.25
|
||||
Revision 1.26
|
||||
</p>
|
||||
|
||||
</GUIDE>
|
||||
|
|
Loading…
Reference in New Issue
Block a user