[KinoSearch] Subclassable Highlighter
Marvin Humphrey
marvin at rectangular.com
Wed Jan 30 17:18:16 PST 2008
On Jan 30, 2008, at 4:17 PM, Father Chrysostomos wrote:
>> Highlighter*
>> Highlighter_new(const char *class_name, Searcher *searcher, Query
>> *query,
>> ByteBuf *field, u32_t excerpt_length, Formatter
>> *formatter,
>> Encoder *encoder)
>
> Does C have such a thing as optional arguments?
There's variadic functions, but this wouldn't really be an
appropriate use for them. You'd have to do something like supply the
args as a NULL-terminated list. Then you have to use the <stdarg.h>
macros. The code gets nasty and hard to follow if you do that.
In Java, you have overloading by message signature, which you can use
for defaulting args:
/** Create a new Highlighter with a default excerptLength of 200.
*/
public Highlighter(Searcher s, Query q, String fld) {
this(s, q, fld, 200); // Calls the constructor below.
}
public Highlighter(Searcher searcher, Query query, String field,
int excerptLength) {
this.searcher = searcher;
this.query = query;
this.field = field;
this.excerptLength = excerptLength;
}
I dislike that technique because it leads to spaghetti code (see
<http://www.rectangular.com/blog/overload_overload.html>), but there
you have it.
One stratagem I considered briefly with KS was making most of the C-
level constructors take a Hash argument.
Highlighter*
Highlighter_new(const char *class_name, Hash *args_hash)
That would allow me to add new() as a method to each class's VTable.
However, that's not idiomatic C -- to say the least! Marshalling
arguments into a hash would be very awkward without hash-manipulation
syntax built into the language.
> Having to pass the query and searcher every time can get a bit
> tedious. How about adding a create_excerpt method to
> KinoSearch::Simple?
Hmm. It would need to take an arg specifying the excerpt field.
$simple->search( query => 'foo bar' );
while ( my $hit = $simple->fetch_hit ) {
my $excerpt = $simple->create_excerpt( hit => $hit, field =>
'content' );
...
}
Another possibility is to add an "excerpt_field" param to
Simple::search, and automatically inserts an "excerpt" member into
the Doc.
$simple->search(
query => 'foo bar',
excerpt_field => 'body',
);
while ( my $hit = $simple->fetch_hit ) {
print qq|
<p>
<strong>$hit->{title}</strong><br />
$hit->{excerpt}
</p>
|;
}
I'm not really enthused about either of those, because Simple's
methods should always resemble the related behaviors of regular KS as
closely as possible.
Marvin Humphrey
Rectangular Research
http://www.rectangular.com/
_______________________________________________
KinoSearch mailing list
KinoSearch at rectangular.com
http://www.rectangular.com/mailman/listinfo/kinosearch
More information about the kinosearch
mailing list