Last active
August 29, 2015 14:15
-
-
Save paulghaddad/e2cccd527e3680879d63 to your computer and use it in GitHub Desktop.
Level Up 7: Considers and guards against error conditions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1. Show some ways that you can make your code more accepting and robust while guarding against errors. | |
Some of the patterns that make code more accepting and robust, while guarding against errors include: | |
- Defining conversions to user-defined types. This allows your method to require an input in the form of a class you defined. But, if possible, it will implicitly convert instances of another class to the needed type. | |
- Use built-in conversion methods, such as Integer or Array, to convert an input into a core type. | |
- Define conversion functions. This allows you to build a public API that accepts inputs in multiple forms. Internally, you will normalize objects to a single type of your own devising. | |
- To guard against unworkable input values that can't be converted or adapted into a usable form, it is best to reject them early, using precondition (guard) clauses. | |
- Use #fetch to assert to presence of a Hash key. This will prevent nil values from occurring when a key is not found in a hash. | |
2. For which code is it more important to guard against errors? For which code is it less important? | |
- A common cause of needless type and nil checks, among other conditions, is not properly using preconditions and type coercion in class initiator methods. This is one situation where it is important to guard against errors and bad conditions. Otherwise, you may find methods throughout your class checking for these conditions; instead poor inputs should be prevented from getting past the initiator. This cleans up your methods by eliminating repetitive guard conditions in them. Assuming the initiator method builds objects using appropriate input values, then it is less important to guard against errors in other methods in the class. | |
- External code that touches other libraries needs more sanitization, whereas internal code (esp. privates) need much less, which is a great way to maintain boundaries. The more we can make private and unalterable, the less we need to worry. | |
3. For the above, why does it matter? | |
The overall reason to carefully consider where guard clauses and error conditions are handled in your code is to produce code that tells a clear narrative. The alternative is to have code littered with special conditions, conditionals and cases. This makes it difficult for others to understand the purpose of the code. We should avoid taking detours and introducing forks. The goal when writing code should be a clear, straightforward path. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment