sub do_stuff {
my ( $self, %args ) = @_;
my $foo = $args{foo};
my $bar = $args{bar};
# ....
}
####
void
do_stuff(self, ...)
SV *self;
PPCODE:
{
HV* args_hash = build_args_hash(args, to, be, named, later);
IV foo = extract_iv(args_hash, "foo", 3);
NV bar = extract_nv(args_hash, "bar", 3);
/* ... */
}
####
IV
extract_iv(hash, key, key_len) {
SV **const sv_ptr = hv_fetch(hash, key, key_len, 0);
if (sv_ptr == NULL) {
croak("Failed to retrieve hash entry '%s'", key);
}
return SvIV(*sv_ptr);
}
####
HV*
build_args_hash()
{
dXSARGS; /* need to declare XS args so that we can use ST(n) later */
HV *args_hash = (HV*)sv_2mortal( (SV*)newHV() ); /* mortalized hash */
kino_i32_t stack_pos = 1;
/* verify that our args come in pairs */
if (items % 2 != 1) {
croak("Expecting hash-style named params, got odd number of args");
}
/* build the hash */
while (stack_pos < items) {
SV *val_sv;
SV *key_sv = ST(stack_pos++);
STRLEN key_len;
char *key = SvPV(key_sv, key_len);
val_sv = ST(stack_pos++);
hv_store(args_hash, key, key_len, newSVsv(val_sv), 0);
}
return args_hash;
}
####
{
PUSHMARK(SP);
HV* args_hash = build_args_hash();
IV foo = extract_iv(args_hash, "foo", 3);
NV bar = extract_nv(args_hash, "bar", 3);
/* ... */
}
####
{
HV *args_hash;
IV foo;
NV bar;
PUSHMARK(SP);
args_hash = build_args_hash();
foo = extract_iv(args_hash, "foo", 3);
bar = extract_nv(args_hash, "bar", 3);
/* ... */
}
####
HV *arg_hash = build_args_hash( &(ST(0)), items );