[Prev][Next][Index][Thread]
Neat little hack: dispatching on keyword args
Hi all,
I've occasionally wanted to write methods that dispatch on keyword
parameters, but this is (rightly) not possible. Anyway, I've found a
simple little trick for working around this.
Suppose I have a method with the following signature
define method repeat(re :: <regexp>,
#key min :: <integer> = 0,
max :: <infinity-or-int> = $infinity)
=> (new :: <regexp>);
and I want to dispatch on different min and max arguments, calling
different constructors for each posisble case. The hack is to define
the method repeat, and make its body just a call to a helper gf that
has min and max as required positional args, and dispatches on them.
For example:
define function repeat(re :: <regexp>,
#key min :: <integer> = 0,
max :: <infinity-or-int> = $infinity)
=> (new :: <regexp>);
helper(re, min, max)
end function repeat;
define method helper(re :: <regexp>, min == 0, max == $infinity)
=> (new :: <regexp>)
re.kleene-closure
end method helper;
define method helper(re :: <regexp>, min :: <integer>, max == $infinity)
=> (new :: <regexp>)
make(<re-sequence>, first: re, second: helper(re, min - 1, max))
end method helper;
define method helper(re :: <regexp>, min == 0, max :: <integer>)
=> (new :: <regexp>)
helper(re.optional, max, max)
end method helper;
[...and so on...]
This is an obvious trick, but I thought I'd share it anyway in case
any of you hadn't seen it before.
Neel