On 05/03/2017 17:26, Bruno Albuquerque wrote:
So, my question is: Using the trick of overriding specific methods form
Analyzer during runtime, is there a way I can also create my own ivars and
attach it to my overriden analyzer?

Yes, this is possible. See the example code below (based on Lucy 0.6). Note that you should implement Equals, Dump, and Load methods if you have an Analyzer with ivars. See the Lucy Analyzers for guidance:

    https://github.com/apache/lucy/tree/master/core/Lucy/Analysis

Another option is to write your own Clownfish parcel. Then the Clownfish compiler 'cfc' will create all the boilerplate code for you.

    https://lucy.apache.org/docs/c/Clownfish/Docs/WritingClasses.html

While we are at this, this is all Lucy 0.4.2 (yeah, I know, old) and I am
considering moving to the latest version mostly due to the now included
golang bindings. I didn't look a lot at the golang bindings yet but will it
be possible to create a new analyzer in a non-hackish way and entirely in
go using it?

Extending Lucy classes from Go isn't supported yet.

Nick


#define CFISH_USE_SHORT_NAMES
#define LUCY_USE_SHORT_NAMES

#include <stdio.h>

#include "Clownfish/Class.h"
#include "Lucy/Analysis/Analyzer.h"
#include "Lucy/Analysis/Inversion.h"

typedef struct MyAnalyzer MyAnalyzer;

typedef struct {
    int i;
    const char *p;
} MyAnalyzerIVARS;

Class *MYANALYZER;
uint32_t MyAnalyzer_IVARS_OFFSET;

static CFISH_INLINE MyAnalyzerIVARS*
MyAnalyzer_IVARS(MyAnalyzer *self) {
   char *ptr = (char*)self + MyAnalyzer_IVARS_OFFSET;
   return (MyAnalyzerIVARS*)ptr;
}

Analyzer*
MyAnalyzer_new() {
    MyAnalyzer *self = (MyAnalyzer*)Class_Make_Obj(MYANALYZER);
    MyAnalyzerIVARS *const ivars = MyAnalyzer_IVARS(self);
    ivars->i = 42;
    ivars->p = "abc";
    return (Analyzer*)self;
}

Inversion*
MyAnalyzer_Transform_IMP(MyAnalyzer *self, Inversion *inversion) {
    MyAnalyzerIVARS *const ivars = MyAnalyzer_IVARS(self);
    printf("i=%d\n", ivars->i);
    return (Inversion*)INCREF(inversion);
}

int
main() {
    lucy_bootstrap_parcel();

    cfish_ClassSpec class_spec = {
        &MYANALYZER,
        &ANALYZER,
        "MyNamespace::MyAnalyzer",
        sizeof(MyAnalyzerIVARS),
        &MyAnalyzer_IVARS_OFFSET,
        0,
        0,
        0,
        0
    };
    cfish_ParcelSpec parcel_spec = {
        &class_spec,
        NULL,
        NULL,
        NULL,
        1   // Number of classes.
    };

    Class_bootstrap(&parcel_spec);
    Class_Override(MYANALYZER, (cfish_method_t)MyAnalyzer_Transform_IMP,
                   LUCY_Analyzer_Transform_OFFSET);

    Analyzer *analyzer = MyAnalyzer_new();
    Analyzer_Transform(analyzer, NULL);
    DECREF(analyzer);

    return 0;
}

Reply via email to