What if we’ll add the “x” feature?
This is the question.
(adapted from) Steven C. McConnell
Well, first of all let’s see what we see 🙂
Indicates whether a file name conforms to the format specified by a filter string.
function MatchesMask(const Filename: string; const Mask: string): Boolean;
Call MatchesMask to check the Filename parameter using the Mask parameter to describe valid values. A valid mask consists of literal characters, sets, and wildcards.Each literal character must match a single character in the string. The comparison to literal characters is case-insensitive.Each set begins with an opening bracket ([) and ends with a closing bracket (]). Between the brackets are the elements of the set. Each element is a literal character or a range. Ranges are specified by an initial value, a dash (-), and a final value. Do not use spaces or commas to separate the elements of the set. A set must match a single character in the string. The character matches the set if it is the same as one of the literal characters in the set, or if it is in one of the ranges in the set. A character is in a range if it matches the initial value, the final value, or falls between the two values. All comparisons are case-insensitive. If the first character after the opening bracket of a set is an exclamation point (!), then the set matches any character that is not in the set.Wildcards are asterisks (*) or question marks (?). An asterisk matches any number of characters. A question mark matches a single arbitrary character.
MatchesMask returns true if the string matches the mask. MatchesMask returns false if the string does not match the mask. MatchesMask raises an exception if the mask is syntactically invalid.
Note: The Filename parameter does not need to be a file name. MatchesMask can be used to check strings against any syntactically correct mask.
(from Delphi’s Help)
So, we have here a very nice function primarily designed to (quote again) Indicates whether a file name conforms to the format specified by a filter string, right? Wrong!…
Let’s use it:
bFail:=MatchesMask('MyFile [FYI-2009] .doc', '* [FYI-2009].doc'); //FAIL! One cannot use '[' and ']' in the names, even if the OS allows it bFail:=MatchesMask('C:\Foo\Bar\Baz\qux.txt', 'C:\*.txt'); //FAIL! (returns True) If you use paths, BE SURE that you know what you're doing!
In my humble opinion, this is one of the typical cases of the “lab overengineering”. Making it more powerful than the first (real) requirement broke the feature’s link with it’s purpose. And this is bad. Very bad. Because now, instead to have one solved problem, there were spent enough resources (men, time, computers, coffee, chips, hair etc.) and succeeded only to create more new problems:
- load: feature which must be maintained but it doesn’t accomplish its initial purpose
- delusion: the thought that everything is ok, while it is not.
- hill to climb: we still need to cover the (still) uncovered need, isn’t it?
Of course, the solution is ‘simple’ ( 🙂 ) : Build a lab and a real-world test case before enhancing – thing which will tell you if the feature (still) keeps the contact with the reality.
There are some variants. Add an escape character. Add a full-blown regular expression engine – thing which it seems that is started already. …and meanwhile we can patch the VCL – thanks God that we have the source.
But first of all, sons, fix that help, because otherwise you lie and the frustration of your customers will return upon you.
Or perhaps someone has another idea?