|Think about Loose Coupling|
XS: parse hash-style named parametersby creamygoodness (Curate)
|on Sep 26, 2006 at 14:19 UTC||Need Help??|
creamygoodness has asked for the
wisdom of the Perl Monks concerning the following question:
I'm trying to build the XS equivalent of the parse-named-params idiom:
Here's how I'd like the XS code to look:
The extract_XX functions are easy -- they're just casting/error-checking wrappers around hv_fetch:
The sticking point is the build_args_hash function. I think I have a solution, but I'm not confident it's the best one.
Here's one version:
Unfortunately dXSARGS, in the process of declaring items, sp, ax, mark and so on, pops a stack marker from the mark stack. Without getting into the gory details of what that means, the effect is that the XS function has to invoke the PUSHMARK macro before calling build_args_hash.
That's not C89-compliant, because PUSHMARK is a statement, not a declaration. :( So we have to declare all of our vars first, and the number of lines of code dedicated to initialization more than doubles.
The answer, I'm sure, is to find the right combination of perlapi variables to pass to build_args_hash, but finding that combo has proved more elusive than I'd expected. It's easy to hack something up, but harder if we constrain ourselves using only well-documented official functions. One possibility is to pass in the address of the first item on the stack and then number of items:
A version of build_args_hash built that way works on my machine, but I'm concerned because it relies on an implementation detail: the stack gets accessed directly as an SV**, rather than using the ST(n) macros. I think it's safe, but I'd like to submit this to the code contributions section and that doesn't seem like best practice. What do you think?
Some chatterbox denizens have suggested that this sort of thing is best done using a Perl helper sub which marshalls the named args into an ordered list and then submits them to an XS routine. That's a perfectly fine approach. However, I have something like 35 XS classes to deal with, and if I solve this problem once, then I can do away with a lot of extra code.
Rectangular Research ― http://www.rectangular.com