Hi list,

Having worked with Perl for a while now, it looks like Perl is going to be
part of my life for some time to come.  So, it's time to get formal about
coding standards and practices.  

First on the list is deciding how to name things.  One standard shows up
frequently (camelBack for method names, choo_choo for local/my variables)
in this newsgroup.  Of course, perldoc perlstyle has a lot to say about
style in general, with some tips related to identifier names.  

If you have a moment, could you please take a look at the following
proposed standard for choosing identifier names, and comment as you see
fit.  It pulls from all the sources available to me so far.  It stops short
of specifying the "one right answer" for a number of cases, pending
feedback from the group.

I realize it's hard to read without formatting, so here's a copy of the
same document, with formatting for readability:

http://www.knology.net/~mcdavis941/codingstandards.html

Thanks very much in advance for any feedback.





#####
# Perl Coding Standards - Naming (Draft)
#####

Motivation:

- want same name for same thing/same concept everywhere 
- want same name "through and through", from one end of the program to the
other, and back again (e.g., temporary variable name <=> object attribute
name <=> object accessor method name <=> database column name) 
- want to conform to "industry standard practices" and "common idioms" as
an aid to code maintainability 
- want to minimize time spent deciding what to call things; want it to be a
"problem solved" 
- want to be able to predict what a thing will be called based on knowledge
of policy rather than having to go look it up for each individual case 

Things to name:

You could slice and dice the cases a lot of ways, but these seem to be the
most relevant. 
- constants 
- package-scoped global variables 
- file- or block-scoped lexical variables (outside of subroutines) 
- subroutine formal parameters 
- subroutine lexical variables 
- subroutines (when not a method) 
- instance methods, public 
- instance methods, private 
- class methods, public 
- class methods, private 
- modules (the actual file) 
- packages, when not used as a class 
- packages, when used as a class 
- object members/attributes/properties, public 
- object members/attributes/properties, private 
- accessor (setter or getter) methods for object member/attribute/property 
- hash keys (when hash serves as data structure) 
- hash keys (when hash serves as "options pack", representing optional
parameters) 
- database tables 
- database table columns 

Attributes of Possible Solutions:

- embedding metadata in variable name (type, scope, role in class
hierarchy, level of indirection) 
- use/prohibition of nonalphanumeric characters 
- case sensitivity/use of case 
- identifier length 
- use of abbreviations 

Issues:

- different parts of end-to-end application have different naming
standards, esp parts supplied by other people/organizations (e.g.,
libraries, CPAN modules, components written in other languages) 
- different parts of end-to-end application place different limits on legal
names (w.r.t. case sensitivity, legal characters such as underscore, length
of identifiers) 
- within CPAN, which could be considered the standard-bearer for Perl
coding, many different standards are in use 

Discussion:

- IMHO it's a lot of trouble and generally NOT worth it to use
Simonyi-style prefixes (e.g.,  lpszFirstName) 
- I am, however, inclined to use some representation of level of
indirection in variable names for fundamental types (not objects) (e.g.,
$first_name, $ref_first_name, $ref_ref_first_name, or something like that,
or maybe something shorter like $r_first_name and $rr_first_name) 
- A common standard is to use camelBack (mixed case) for method names and
choo_choo (all lower case, embedded underscores) for local/lexical variables 
- It has been suggested that developers for whom English is a foreign
language find it easier to make sense of names when the variable uses
embedded underscores rather than mixed case 
- When facing a tough issue in life, it always helps to ask ... WWLD (What
Would Larry Do?);  Accordingly, here are guidelines from perldoc perlstyle: 

    -- While short identifiers like $gotit are probably ok, use underscores
to separate words. It is generally easier to read $var_names_like_this than
$VarNamesLikeThis, especially for non-native speakers of English. It's also
a simple rule that works consistently with VAR_NAMES_LIKE_THIS. 
    -- Package names are sometimes an exception to this rule. Perl
informally reserves lowercase module names for ``pragma'' modules like
integer and strict. Other modules should begin with a capital letter and
use mixed case, but probably without underscores due to limitations in
primitive file systems' representations of module names as files that must
fit into a few sparse bytes. 
    -- You may find it helpful to use letter case to indicate the scope or
nature of a variable. For example: 
        --- $ALL_CAPS_HERE   constants only (beware clashes with perl vars!) 
        --- $Some_Caps_Here  package-wide global/static 
        --- $no_caps_here    function scope my() or local() variables 
        --- Function and method names seem to work best as all lowercase,
e.g., $obj->as_string(). 
    -- You can use a leading underscore to indicate that a variable or
function should not be used outside the package that defined it. 
    
Resulting Candidate Standards for Identifier Naming:

    - Constants

    All caps, with underscores to separate words, e.g.,
CONSTANT_NAMES_LIKE_THIS
    No controversy here; this one is a confidence-builder.

    - Package-scoped global variables

    perldoc/perlstyle suggests both mixed-case and embedded underscores,
e.g., $Some_Caps_Here.

    - File- or block-scoped lexical variables (outside of subroutines)

    perldoc/perlstyle suggests using the same approach as for
package-scoped variables; see above. 

    - Subroutine formal parameters

    perldoc/perlstyle suggests embedded underscores, all lower case, e.g.,
$no_caps_here.

    - Subroutine-scoped lexical variables

    perldoc/perlstyle suggests embedded underscores, all lower case, e.g.,
$no_caps_here.

    - Subroutines (when not a method)

    perldoc/perlstyle suggests embedded underscores, all lower case, e.g.,
as_string().

    - Instance methods, public

    perldoc/perlstyle suggests embedded underscores, all lower case, e.g.,
$obj->as_string().
    Other languages such as Java want to see this as mixed-case, e.g.,
$obj.asString(). For example, see
http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_
2e/web-tier/web-tier5.html .
    A quick survey of CPAN shows both styles in common use.

    - Instance methods, private

    perldoc/perlstyle suggests embedded underscores, all lower case, with
leading underscore, e.g., $obj->_as_string().

    - Class methods, public

    perldoc/perlstyle suggests embedded underscores, all lower case, e.g.,
PackageName->as_string().
    Other languages such as Java want to see this as mixed-case, e.g.,
$obj.asString() (with whatever the class method syntax is for Java). 
    A quick survey of CPAN shows both styles in common use.

    - Class methods, private

    perldoc/perlstyle suggests embedded underscores, all lower case, with
leading underscore, e.g., PackageName->_as_string().

    - Modules (the actual file)

    perldoc/perlstyle suggests mixed case, beginning with capital letter,
without underscore. He also seems to presume that module name and package
name will be the identical (with module filename, of course, having the
extra .pm on the end), even though this is not necessarily the case, as
modules may contain multiple packages having names which may bear no
relation to the module name.
    A quick survey of CPAN shows several styles in use (e.g., baseName.pm,
BaseName.pm), but most commonly with first letter capitalized, frequently
mixed case (capitalizing each word) and almost universally without underscore.

    - Packages, when not used as a class

    Same as for module above, without the .pm.

    - Packages, when used as a class

    I have not seen any standard for this. Most commonly, there is no extra
designation. Also seen: PackageNameClass, CPackageName.

    - Object members/attributes/properties, public 

    No explicit mention in perldoc/perlstyle. Should probably use same
standard as for subroutine-scoped lexical variables.

    - Object members/attributes/properties, private 

    No explicit mention in perldoc/perlstyle. Should probably use same
standard as for subroutine-scoped lexical variables, prefixed with an
underscore to indicate that it should not be modified outside of the
package in which the object is defined.

    - Accessor (setter or getter) methods for object
member/attribute/property 

    Many different approaches in use. For attribute 'name', the following
have been seen: 

        -- $obj->name / $obj->name( $value ) # getter / setter 
        -- $obj->get_name / $obj->set_name 
        -- $obj->getName / $obj->setName 

    And, for longer attribute names: 

        -- $obj->longer_name / $obj->longer_name( $value ) # getter / setter 
        -- $obj->longerName / $obj->longerName( $value ) 
        -- $obj->get_longer_name / $obj->set_longer_name 
        -- $obj->get_longerName / $obj->set_longerName 
        -- $obj->getLongerName / $obj->setLongerName 

    I'm inclined to go with this last one: I like the explicit use of get
and set in method name (makes explicit what would otherwise be implicit
behavior, improving code readability), even though it has the downside of
requiring a transformation (first-letter capitalization) of attribute name.

    - Hash keys (when hash serves as data structure)

    In this case, the hash is used as a data structure (the Perl equivalent
of a C struct).
    Probably should apply same rule as for subroutine-scoped lexical
variables; namely, all lower case, with embedded underscores.

    - Hash keys (when hash serves as "options pack", representing optional
parameters)

    Many different approaches in use: 

        -- all caps, e.g., { CREATE=>1 } as in AppConfig.pm 
        -- lowercase with embedded underscores, e.g., { flush_imports => 1
} as in App::Options 
        -- lowercase with embedded underscores, with leading dash, e.g., [
-target_class => 'X' ] as in Class::MethodMaker 
        -- mixed case, no underscores, e.g., { RaiseError => 1, AutoCommit
=> 0 } as in DBI 
        -- and probably, somewhere, all caps and mixed-case with leading
dash, although I didn't see it in a quick review 

    I like the use of the dash; to me, it instantly communicates that this
in an option which may be omitted, distinguishing it from hash as data
structure. Should probably use whatever standard is used for
function-scoped lexical variables. 

    - Database tables

    Often, would like to maintain correspondence between table name and
class/object name. This would be driven by restrictions on table name;
information about restrictions imposed by common database packages is TBD.
    [ ] TODO: MySQL; Oracle; MS SQL Server.

    - Database table columns

    Often, would like to maintain correspondence between column name and
class member/property/attribute/method name. This would be driven by
restrictions on column names; information about restrictions imposed by
common database packages is TBD.
    [ ] TODO: MySQL; Oracle; MS SQL Server.

End of document.

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to