3 ms·
This gets especially horrible with multiple arguments, each of which is a bool. foo.frob(true, false, true); and now try to figure out what each of them m
by ygra 12y ago
This gets especially horrible with multiple arguments, each of which is a bool.
foo.frob(true, false, true);
and now try to figure out what each of them means. It can get better with explicitly stating argument names, but that's only a temporary stopgap.
The »two methods, distinguished in name« works fine, as long as you only have a single boolean argument and API growth won't ever happen around that point. Other options that often scale better would be enums, or a parameter object encompassing options, if there are many.
- BurningFrog 12y agoWe used to call that "boolean salad" at an old job.
- philh 12y agoSomething I occasionally saw people do in lisp was (frob foo :quick (not :sneaky) :force) which could be done with strings in other languages foo.frob('quick', not 'sneaky', 'force') It's not ideal, because it makes it look like the arguments mean something. But if someone remembers that frob takes three boolean arguments, but doesn't remember what order they come in, this could be handy. Another option would be foo.frob(bool('quick'), not bool('sneaky'), bool('force')) but that's kind of verbose. EDIT: And the D approach posted above inspires this idea in python: class _ConstAttr: def __init__(self, const): self.const = const def __getattr__(self, attr): return self.const Yes = _ConstAttr(True) No = _ConstAttr(False) foo.frob(Yes.quick, No.sneaky, Yes.force) (It wouldn't be much use in Python, because of keyword arguments, but there might be languages without keyword arguments that could implement something like this. E.g. C macros YES(x) -> 1, NO(x) -> 0. It looks like D enforces the attribute name, so you can't get the arguments mixed up when writing and say No.sneaky, Yes.quick. It would be nice to get that as well.)
- ekimekim 12y agoOne solution I've seen is to use two unique string values instead of True/False, and reject all other string values. eg. foo.frob("quick", "loud", "noforce") foo.frob("slow", "sneaky", "force") foo.frob("fast", "sneaky", "force") # this errors EDIT: Naturally I'd prefer a type-safe approach in languages that offer it, but this is a common solution I've seen in the python world.