[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