in reply to Write "Dumber" Functions
I strongly disagree. There is a difference between a programming error and a data validation failure and I want to minimize the odds of a programming error being interpretted as a data validation failure.
The function is documented as telling you whether three numbers correspond to a valid date. If you give it something other than 3 values, the correct reponse is neither "true" nor "false". That is considered a programming error (failure to pass in the information required) and not a data validation failure.
You can argue that what exactly is a usage error and how such are treated should be documented. I won't argue too strongly against that, but I do see value in not over specifying such things as avoiding that means that you have some room to improve the interface in the future.
Since you broke the contract defined in the documentation, you should not expect the function to stick to the contract in the documentation either. In some respects, it is free to do anything it wants to. It can emit warnings, errors, and/or kill the program. It can even return "true" (hopefully after emitting at least a warning). It is best if it simply reports the usage error so that you can fix your program mistake (which is what it did) and stops the program so that it doesn't continue on to do the wrong thing.
The function is documented as validating whether three numbers form a proper date. You seem to think that it should do more than it is documented to do and also validate for you whether you have more or fewer than 3 numbers. You want the function to be "smarter" not dumber. You want it to do more, because you didn't want to do the work of verifying that the user had given you three numbers.
Now, I do agree that sometimes it is a fine line between programming error and data validation failure, especially in Perl. You could certainly make the case that having more or fewer than 3 numbers should constitute a data validation failure here. But, if you do that, then you'd have to update the documentation to the function so that it says something more like "this function takes a list of numbers and returns a true value if the list contains exactly three numbers and ...". And I like that interface definition less than the original one.
Perl is quite nice in that is does a good job of supporting two quite different forms of programming: quick hacks and 'developed' software.
Sure, for some quick hacks, it might be convenient for the function to simply return "false" in the case of such invalid usage. And the rest of your code does look like "quick hack" code in some respects. You are shifting values out of @ARGV w/o knowing that there is anything to get. Your code would generate warning is you had such enabled.
But code from modules is usually geared more toward 'developed' software. And I'm glad of that.
I think this problem could have served as a "wake up" call and gotten you to look at your own code and your own assumptions more closely. Instead, you chose to look at the module and consider it at fault for not supporting this particular usage. But I find fault with the basic approach that your code takes, and I am glad that the module does not support it.
If I enter an invalid date on the command line, then the last thing I want to happen is for the program to use some other date that it chooses and continue on. In many cases that is a recipe for major problems. In the best case, it is a recipe for frustration.
I certainly agree that it is nice to have "defaults". And it might be nice for this particular program to default to "today" if no date is given. But you'd code that much differently than you have.
There are cases where you want your program to trudge on in the face of adversity and try to do something with its best guess as to how to overcome minor problems. Otherwise you can have programs that are too fragile and refuse to work too often. But I don't think this is such as case at all. - tye (but my friends call me "Tye")use Date::Calc qw/ check_date Localtime /; my @date; if( 0 == @ARGV ) { warn( 'Using current date.\n' ); @data= (Localtime)[0..2]; } els... ... croak( 'Invalid date supplied from command line' ); ...
|
|---|