I'm writing Ruby code for a simple encryption exercise and have frequently run across this dilemma (the exercise is a solitaire cipher if you must know). It is a question of whether I should pad out my logic with descriptive variables and single step statements that make the function readable instead of a concise, even dense statements that eliminate repetition and/or minimizes opportunities for errors.
My most recent example: My program takes input, and because of rigid format guidelines, it can easily determine if input should be encrypted or decrypted. To simplify, once the encryption key and message are converted/generated to be compatible, it's a matter of subtracting the key from the encrypted message or adding the key to an unencrypted message, to get the desired output(think of the key as encryption, message + encryption = code; code - encryption = message). The DRY position says to me that I should convert my encrypted message differently from my unencrypted message so that the function which takes encryption key and applies it to the message never needs to distinguish. I've found that this means I need some nested if statements in the function but the logic appears to be solid. This code, however, is not easily readable. This would require some commenting to be clear.
I could, on the other hand, write two different functions that are called based on a flag that is set when the application determines encryption or decryption. This would be simpler to read but would duplicate the high level function of applying the encryption key to a message (causing it to be encrypted or decrypted).
Should I lean toward readable code, or concise code? Or have I missed another way to get this functionality and satisfy both principles? Is it a position along a scale in which one must consider the purpose of the project and make the best decisions to serve that purpose?
So far, I tend to emphasize concise, DRY code over readable code.