On this page, we describe all the guidelines for interacting with the code and other devs. Always feel free to suggest better ways of working with one another.
Etiquette for Posting Bugs & Communicating with Devs
Because of the unique structure of teams on an open-source project, communications between each dev, and between devs and bug posters can be very challenging: Devs with different amounts of time commitments and knowledge about the project must all work together, all the while responding to the very important bug-reports by people outside the project who have almost no experience. We need to create an open environment where everyone feels free to communicate their ideas. Here's our list of guidelines to promote good communication.
Communicating with Devs in the Forums and over Email
- Avoid private discussions, especially to solve problems - More specifically, if a discussion doesn't need to be private (an one-on-one email), then make it public by posting it to the forums!
Why? Because we want encourage new participants to feel comfortable contributing to the discussion, and private discussions tend to lead to "inner circles" (yes, we old hands can often start to shut out the newer members - not a good thing). Also, a public forum often becomes a great archive for all our past knowledge. Help us build our collective information!
- Zero tolerance for rudeness - Most devs have strong opinions and are often not afraid to vocalize them! (just a trait of being smart, right?:) When people interact over written-communication, it's often easier to be more aggressive and honestly meaner than it is in person. No personal attacks or name calling! We're going to disagree about issues, but stop all potential flame wars right away. They're waste of everyone's time and energy.
Posting Bugs & Requesting Features
Before posting a bug or requesting a new feature to the bug tracker, always do two things:
- Search the Bug Tracker for an existing or past bug. There tends to be a lot of duplicate submissions, which wastes our devs a lot of time. Please help us keep the duplicates down to a minimum!
- Post your bug to the forums to see if one of the old hands knows of an existing bug. Again, let's keep the duplicates down!
We really want our user community to post any bugs they find - these are invaluable to helping us create bullet-proof software! We'll never be harsh on you if you post a duplicate, but most open-source projects have bug tracking systems filled with redundant bugs, making the tracker a pain to manage and much less useful. Help us keep the tracker as clean as possible. Thanks!
Here, on Project Hierarchy, we encourage people to present all their ideas and to let their voices be heard. But, when it comes time to make tough decisions, our decision-making structure is a 'Benevolent Dictatorship' (with an emphasis on 'benevolent'). For those who have never heard of the term, this means that final decision on issues are made by the project leads. We've found this is the best structure for us to balance openness with productivity.
Contributing your Code
We use Github as our source control management. And, when submitting code to the project, please follow our general coding standards.
Naming using Both Camel-Case and Underscores
For naming our class, packages and methods, we used a system that mixes both camel case and underscores. It can be a little foreign to those who have never seen it before, but it's pretty simple once you've used for a couple of hours. We use this mixed system in two ways:
- Hierarchical naming - This is mainly used for the names of classes. Basically what you're doing is adding group names into the class name. This is easier to explain with an example. Let's say your creating a search-engine component for an online address book. You have the following classes:
- SearchEngine - This is a facade class that wraps the entire SearchEngine component.
- Query - This is a query class that is used when a user is creating a search. It is filled with the search terms and symbols he uses.
- SearchTerm - This is a search term used in a query, such as 'Thomas' or 'Sally.'
- Operator - This a search operator used in a query, like 'AND' or 'OR'.
The problem with these class names is that they are in a package called contactlist.search, which has many other class mixed in. Typically, when we list this directory in a terminal window, it's ordered alpahbetically, and what we see is this:
This list tells us nothing about what classes belong together. It's really quite a mess. So instead, we add 'group prefixes' to the names to put all classes of the same component together. So, to bring all the classes of the Query component together, we'd do the following:
QueryOperator <- Added Query prefix
QuerySearchTerm <- Added Query prefix
But actually, the Optimizer class also belongs with the Query component as it is used to optimize the query. But if we simply add the 'Query' prefix to the class name, the Optimizer class will be mixed in with the search terms:
QueryOptimizer <- This should not be here!
So, what we can do is to further group the class names into 'sub groups' by adding another prefix after Query:
QueryOptimizer <- Ah! Much better!
Now, everything that should be grouped together is right next to one another. Yay!
But, as a last optimization (here's where the underscores come in), just using camel case can lead to confusion as to what the groupings are. For instance, for the QueryGrammarSearchTerm class, the groups and subgroups for this could be interpreted like this:
Query / GrammarSearch / Term <-- Bad intepretation of groups!!
Which is not what we had intended! Just using camel case leads to ambiguous groupings. For a simple packages with just a few classes, this is not a big deal, but most packages tend to grow and grow, and things can get confusing quickly. So, we add underscores to separate the different group names to help clarify the different parts. This leads us to:
So, to interpret the name of this class, what we get is:
- Query - is the first-level group-name of the class.
- Grammar - is the second-level group-name for this class.
- SearchTerm - is the actual name of the class itself! This is important: the last part of a hierarchical name is the name of the class if it had no groups!
This is so important, we'll say it again - The last part of a hierarchical name is the name of the class if it had no groups! Once you get used it, it makes a lot of sense and is easy to understand. Just keep in mind the whole idea of grouping is to let us keep related classes together.
One question you may have is, 'Why don't you just move these related classes into their own package?' There are many reasons why you shouldn't do this. The main one is that moving a group of class into its own package should not be done just to keep the naming of classes clearer. Packages are a major organizational structure that actually changes the physical location of the classes. We should only be moving classes into a new package if there is a larger, more structural reason to do so!
- Easier-to-Read Method-Names - This usage of 'mixing camel case with underscores' is much more debatable as to whether it's helpful. It's pretty simple. All you're doing is making method names more readable by grouping different parts of the name together. Again, this is much easier to show than to explain, so let's take the ContactList class again and then add the following method:
This can be interpreted in two ways:
In this first interpretation, the method name is seen like this: 'search-terms database,' with an implied hyphen between 'search' and 'terms.' For this interpretation, the purpose for this method is that it simply returns the search-terms DB object.
But, another possible interpretation could be:
In this second interpretation, there is an implied hyphen between 'terms' and 'database,' which would result in an interpretation like this: 'search terms-database.' The possible purpose of this method would then be to perform a search on the terms database and return the search results. So, to clarify this method name, we can simply add underscores to separate the different parts:
Ah! Much better! The unambiguous interpretation of this method is that it does a search operation. Great!
Now, you might say this seems like overkill and you can often figure out the meaning of a method name by looking at the comments or the code, but this isn't always possible (often, the code is not available and/or the dev didn't write any comments). Also, when a class gets complex with maybe dozens of different search methods each with its own nuances, it can become even more difficult to interpret the name. The goal here is to make it as easy as possible for a new dev using this class to understand the meaning of any name. If using a few, well-placed underscores helps him avoid a few moments of frustration, we should probably spend a little time and add them in.