[ 
https://issues.apache.org/jira/browse/LUCY-27?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Marvin Humphrey updated LUCY-27:
--------------------------------

    Attachment: Constructor.pm
                Method.pm
                Subroutine.pm

Boilerplater::Binding::Perl::Method, Boilerplater::Binding::Perl::Constructor,
and their common abstract parent, Boilerplater::Binding::Perl::Subroutine, are
responsible for autogenerating complete XSubs which allow public Lucy methods to
be invoked from Perl. 

Methods which take two or more arguments will be automatically set up to take
labeled, hash-style parameters.  Methods which take one arg will be set up to
take a an unlabeled positional argument:

{code:none}
my $query = $query_parser->parse($query_string);    # positional arg
my $hits  = $searcher->hits(                        # labeled params
    query      => $query,
    num_wanted => 20,
);
{code}

Constructors always take labeled parameters, even if the C constructor only
takes one argument.

{code:none}
my $folder = Lucy::Storage::FSFolder->new(
    path => '/path/to/folder',
);
{code}

Default argument values are extracted from the Boilerplater::ParamList
signature and baked into the C code of the XSub itself.  If a parameter is
either not supplied or supplied as undef, the default value will be used when
invoking the C function.  If there is no default value and a parameter is
either missing or undef, an error will occur.  

Supplying an unrecognized parameter also results in an error.   Validation is
implemented using an autogenerated package global Perl hash, one per method
binding.  When the method is invoked from Perl-space, each label is checked
for existence in this hash:

{code:none}
our %Lucy::Storage::FSFolder::new_PARAMS = (
    path => undef,
);
{code}

The names of these parameter labels are taken from the variable names in the
Boilerplater function signature -- which is why argument names are considered
part of the public API for a Boilerplater function, and why the Boilerplater
compiler throws an error if a method which overrides another has a conflicting
argument name.  Changing an arg name would cause the contents of this hash to
change and existing invocations to start throwing "unrecognized parameter"
errors.

{code:none}
my $hits = $searcher->hits(
    query         => $query,
    invalid_param => 'kaboom',
);
{code}

Methods must be bound from the class under which they are first declared; that
implementation, and all subclass implementations then get their own dedicated
XSub.  The C function which implements the method is then invoked directly
rather than via Lucy's vtable dynamic dispatch -- i.e. lucy_Searcher_hits() is
invoked rather than Lucy_Searcher_Hits().  It may seem wasteful to generate so
many XSubs, but in fact doing things this way is crucial to subclassing, as
the more compact technique is not compatible with Perl's SUPER method
invocation syntax.

> Boilerplater Perl bindings
> --------------------------
>
>                 Key: LUCY-27
>                 URL: https://issues.apache.org/jira/browse/LUCY-27
>             Project: Lucy
>          Issue Type: Sub-task
>          Components: Boilerplater
>            Reporter: Marvin Humphrey
>         Attachments: Constructor.pm, Method.pm, Subroutine.pm, TypeMap.pm
>
>
> Iterate over the classes, methods, etc. in a Boilerplater::Hierarchy, 
> auto-generating binding code to bridge Perl-space and C-space.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to