|Think about Loose Coupling|
KISS vs Feature setby Masem (Monsignor)
|on Jan 25, 2002 at 17:39 UTC||Need Help??|
I was in the process of tidying up my File::Grep code last night and came across a dilemma. I've redone most of the code such that using closures, the main grepping routine is located in one single function, and the user-callable functions simply need to call that with their closure. Thus, besides fgrep, I was able to implement fmap (analogous to map) and fdo (analogous to a foreach statement, but of a form consistent with fgrep/fmap). I mentioned in my original post here that I was considering adding other functions to provide more features, but that was before I rewrote the code to provide better hooks.
One example was that in the case where the fgrep was called with wantarray, the sub would have returned an array of hashes, one for each file in the list. The hashes had the number of matches, the matches themselves, etc. However, I realize that some would have not wanted the results back that way, instead, just wanting a flat array. So I was considering writing an "fgrep_flat" function which would return that array. However, given that I've provide 'fdo', it's just trivial for the user to create this functionality themselves if they need it. So theorhetically, there's no need for me to include it.
A second example is that array of hashes itself. It would be documented in the POD of course, but it requires the user to know what to expect from it. Alternatively, if I simply had fgrep return an array with the matches in it, there's no question what fgrep would return and would make it very simple. If a user really wanted a detailed set of information from the matches, he could simply use fdo or fmap to create that set for himself, and with the specification that he wants.
Adding the additional functions would of course not affect performance in any way, but would have to make assumptions about how the user is accessing the module and their data. It would seem to me that in this case, it's better to follow the KISS (Keep it Simple, Stupid) policy and only provide, strictly, the fgrep/fmap/fdo functions, and allow the user to modify their code to meet what they want, itself of trying to guesswork at what the user wants and provide functions that increase the functionality but with possibly odd return types.
So in general, it would seem to me that if you have the option of adding more functionality to something but at the cost of having to guesswork how the end user would handle it, it's not a good idea. But if the return type is straightforward (a scalar, a list, or similar) that requires little explaination, it can't hurt to include it (as an example I point to DBI's fetchrow_ functions, only 1 which is really needed, but the others are more efficient but don't have difficult return types).
Any other rules of thumbs or suggestions on this (for the module itself or in general?)
Update in can