VEC(Param) named_required;
VEC(ParamInit) named_optional;
Param slurpy;
+ PADOFFSET rest_hash;
};
DEFVECTOR_INIT(pv_init, Param);
pv_init(&ps->named_required);
piv_init(&ps->named_optional);
p_init(&ps->slurpy);
+ ps->rest_hash = NOT_IN_PAD;
}
#define DEFVECTOR_EXTEND(N, B) static B (*N(VEC(B) *p)) { \
return mkargselem(aTHX_ my_var(aTHX_ 0, v));
}
+static OP *mkhvelem(pTHX_ PADOFFSET h, OP *k) {
+ OP *hv = my_var_g(aTHX_ OP_PADHV, OPf_REF, h);
+ return newBINOP(OP_HELEM, 0, hv, k);
+}
+
+static OP *mkconstsv(pTHX_ SV *sv) {
+ return newSVOP(OP_CONST, 0, sv);
+}
+
+static OP *mkconstiv(pTHX_ IV i) {
+ return mkconstsv(aTHX_ newSViv(i));
+}
+
+static OP *mkconstpv(pTHX_ const char *p, size_t n) {
+ return mkconstsv(aTHX_ newSVpv(p, n));
+}
+
+#define mkconstpvs(S) mkconstpv(aTHX_ "" S "", sizeof S - 1)
+
static int parse_fun(pTHX_ OP **pop, const char *keyword_ptr, STRLEN keyword_len, const KWSpec *spec) {
ParamSpec *param_spec;
SV *declarator;
}
if (attr) {
- *attrs_sentinel = op_append_elem(OP_LIST, *attrs_sentinel, newSVOP(OP_CONST, 0, SvREFCNT_inc_simple_NN(attr)));
+ *attrs_sentinel = op_append_elem(OP_LIST, *attrs_sentinel, mkconstsv(aTHX_ SvREFCNT_inc_simple_NN(attr)));
}
if (c == ':') {
newATTRSUB(
sub_ix,
- newSVOP(OP_CONST, 0, SvREFCNT_inc_simple_NN(saw_name)),
- proto ? newSVOP(OP_CONST, 0, SvREFCNT_inc_simple_NN(proto)) : NULL,
+ mkconstsv(aTHX_ SvREFCNT_inc_simple_NN(saw_name)),
+ proto ? mkconstsv(aTHX_ SvREFCNT_inc_simple_NN(proto)) : NULL,
NULL,
NULL
);
if (amin > 0) {
OP *chk, *cond, *err, *croak;
- err = newSVOP(OP_CONST, 0,
- newSVpvf("Not enough arguments for %"SVf" (expected %d, got ", SVfARG(declarator), amin));
- err = newBINOP(OP_CONCAT, 0,
- err,
- newAVREF(newGVOP(OP_GV, 0, PL_defgv)));
- err = newBINOP(OP_CONCAT, 0,
- err,
- newSVOP(OP_CONST, 0, newSVpvs(")")));
+ err = mkconstsv(aTHX_ newSVpvf("Not enough arguments for %"SVf" (expected %d, got ", SVfARG(declarator), amin));
+ err = newBINOP(
+ OP_CONCAT, 0,
+ err,
+ newAVREF(newGVOP(OP_GV, 0, PL_defgv))
+ );
+ err = newBINOP(
+ OP_CONCAT, 0,
+ err,
+ mkconstpvs(")")
+ );
croak = newCVREF(OPf_WANT_SCALAR,
- newGVOP(OP_GV, 0, gv_fetchpvs("Carp::croak", 0, SVt_PVCV)));
+ newGVOP(OP_GV, 0, gv_fetchpvs("Carp::croak", 0, SVt_PVCV)));
err = newUNOP(OP_ENTERSUB, OPf_STACKED,
- op_append_elem(OP_LIST, err, croak));
+ op_append_elem(OP_LIST, err, croak));
cond = newBINOP(OP_LT, 0,
- newAVREF(newGVOP(OP_GV, 0, PL_defgv)),
- newSVOP(OP_CONST, 0, newSViv(amin)));
+ newAVREF(newGVOP(OP_GV, 0, PL_defgv)),
+ mkconstiv(aTHX_ amin));
chk = newLOGOP(OP_AND, 0, cond, err);
*prelude_sentinel = op_append_list(OP_LINESEQ, *prelude_sentinel, newSTATEOP(0, NULL, chk));
if (amax >= 0) {
OP *chk, *cond, *err, *croak;
- err = newSVOP(OP_CONST, 0,
- newSVpvf("Too many arguments for %"SVf" (expected %d, got ", SVfARG(declarator), amax));
- err = newBINOP(OP_CONCAT, 0,
- err,
- newAVREF(newGVOP(OP_GV, 0, PL_defgv)));
- err = newBINOP(OP_CONCAT, 0,
- err,
- newSVOP(OP_CONST, 0, newSVpvs(")")));
+ err = mkconstsv(aTHX_ newSVpvf("Too many arguments for %"SVf" (expected %d, got ", SVfARG(declarator), amax));
+ err = newBINOP(
+ OP_CONCAT, 0,
+ err,
+ newAVREF(newGVOP(OP_GV, 0, PL_defgv))
+ );
+ err = newBINOP(
+ OP_CONCAT, 0,
+ err,
+ mkconstpvs(")")
+ );
- croak = newCVREF(OPf_WANT_SCALAR,
- newGVOP(OP_GV, 0, gv_fetchpvs("Carp::croak", 0, SVt_PVCV)));
+ croak = newCVREF(
+ OPf_WANT_SCALAR,
+ newGVOP(OP_GV, 0, gv_fetchpvs("Carp::croak", 0, SVt_PVCV))
+ );
err = newUNOP(OP_ENTERSUB, OPf_STACKED,
- op_append_elem(OP_LIST, err, croak));
+ op_append_elem(OP_LIST, err, croak));
- cond = newBINOP(OP_GT, 0,
- newAVREF(newGVOP(OP_GV, 0, PL_defgv)),
- newSVOP(OP_CONST, 0, newSViv(amax)));
+ cond = newBINOP(
+ OP_GT, 0,
+ newAVREF(newGVOP(OP_GV, 0, PL_defgv)),
+ mkconstiv(aTHX_ amax)
+ );
chk = newLOGOP(OP_AND, 0, cond, err);
*prelude_sentinel = op_append_list(OP_LINESEQ, *prelude_sentinel, newSTATEOP(0, NULL, chk));
OP *chk, *cond, *err, *croak;
const UV fixed = count_positional_params(param_spec) + !!param_spec->invocant.name;
- err = newSVOP(OP_CONST, 0,
- newSVpvf("Odd number of paired arguments for %"SVf"", SVfARG(declarator)));
+ err = mkconstsv(aTHX_ newSVpvf("Odd number of paired arguments for %"SVf"", SVfARG(declarator)));
- croak = newCVREF(OPf_WANT_SCALAR,
- newGVOP(OP_GV, 0, gv_fetchpvs("Carp::croak", 0, SVt_PVCV)));
+ croak = newCVREF(
+ OPf_WANT_SCALAR,
+ newGVOP(OP_GV, 0, gv_fetchpvs("Carp::croak", 0, SVt_PVCV))
+ );
err = newUNOP(OP_ENTERSUB, OPf_STACKED,
- op_append_elem(OP_LIST, err, croak));
+ op_append_elem(OP_LIST, err, croak));
cond = newBINOP(OP_GT, 0,
- fixed
- ? newBINOP(OP_SUBTRACT, 0,
- newAVREF(newGVOP(OP_GV, 0, PL_defgv)),
- newSVOP(OP_CONST, 0, newSVuv(fixed)))
- : newAVREF(newGVOP(OP_GV, 0, PL_defgv)),
- newSVOP(OP_CONST, 0, newSViv(0)));
+ newAVREF(newGVOP(OP_GV, 0, PL_defgv)),
+ mkconstiv(aTHX_ fixed));
cond = newLOGOP(OP_AND, 0,
- cond,
- newBINOP(OP_MODULO, 0,
- fixed
- ? newBINOP(OP_SUBTRACT, 0,
- newAVREF(newGVOP(OP_GV, 0, PL_defgv)),
- newSVOP(OP_CONST, 0, newSVuv(fixed)))
- : newAVREF(newGVOP(OP_GV, 0, PL_defgv)),
- newSVOP(OP_CONST, 0, newSViv(2))));
+ cond,
+ newBINOP(OP_MODULO, 0,
+ fixed
+ ? newBINOP(OP_SUBTRACT, 0,
+ newAVREF(newGVOP(OP_GV, 0, PL_defgv)),
+ mkconstiv(aTHX_ fixed))
+ : newAVREF(newGVOP(OP_GV, 0, PL_defgv)),
+ mkconstiv(aTHX_ 2)));
chk = newLOGOP(OP_AND, 0, cond, err);
*prelude_sentinel = op_append_list(OP_LINESEQ, *prelude_sentinel, newSTATEOP(0, NULL, chk));
lhs = op_append_elem(OP_LIST, lhs, var);
}
- if (param_spec->slurpy.name) {
- if (count_named_params(param_spec)) {
- OP *const var = my_var_g(
- aTHX_
- SvPV_nolen(param_spec->slurpy.name)[0] == '@' ? OP_PADAV : OP_PADHV,
- OPf_MOD | (OPpLVAL_INTRO << 8),
- param_spec->slurpy.padoff
- );
- *prelude_sentinel = op_append_list(OP_LINESEQ, *prelude_sentinel, newSTATEOP(0, NULL, var));
+ {
+ PADOFFSET padoff;
+ I32 type;
+ bool slurpy_hash;
+
+ /*
+ * cases:
+ * 1) no named params
+ * 1.1) slurpy
+ * => put it in
+ * 1.2) no slurpy
+ * => nop
+ * 2) named params
+ * 2.1) no slurpy
+ * => synthetic %{rest}
+ * 2.2) slurpy is a hash
+ * => put it in
+ * 2.3) slurpy is an array
+ * => synthetic %{rest}
+ * remember to declare array later
+ */
+
+ slurpy_hash = param_spec->slurpy.name && SvPV_nolen(param_spec->slurpy.name)[0] == '%';
+ if (!count_named_params(param_spec)) {
+ if (param_spec->slurpy.name) {
+ padoff = param_spec->slurpy.padoff;
+ type = slurpy_hash ? OP_PADHV : OP_PADAV;
+ } else {
+ padoff = NOT_IN_PAD;
+ type = OP_PADSV;
+ }
+ } else if (slurpy_hash) {
+ padoff = param_spec->slurpy.padoff;
+ type = OP_PADHV;
} else {
+ padoff = param_spec->rest_hash = pad_add_name_pvs("%{rest}", 0, NULL, NULL);
+ type = OP_PADHV;
+ }
+
+ if (padoff != NOT_IN_PAD) {
OP *const var = my_var_g(
aTHX_
- SvPV_nolen(param_spec->slurpy.name)[0] == '@' ? OP_PADAV : OP_PADHV,
+ type,
OPf_WANT_LIST | (OPpLVAL_INTRO << 8),
- param_spec->slurpy.padoff
+ padoff
);
+
lhs = op_append_elem(OP_LIST, lhs, var);
+
+ if (type == OP_PADHV) {
+ param_spec->rest_hash = padoff;
+ }
}
}
}
}
- /* default arguments */
+ /* default positional arguments */
{
size_t i, lim, req;
OP *nest;
cond = newBINOP(
OP_LT, 0,
newAVREF(newGVOP(OP_GV, 0, PL_defgv)),
- newSVOP(OP_CONST, 0, newSViv(req + i + 1))
+ mkconstiv(aTHX_ req + i + 1)
);
var = my_var(aTHX_ 0, cur->param.padoff);
/* named parameters */
if (count_named_params(param_spec)) {
+ size_t i, lim;
+
+ assert(param_spec->rest_hash != NOT_IN_PAD);
+
+ for (i = 0, lim = param_spec->named_required.used; i < lim; i++) {
+ Param *cur = ¶m_spec->named_required.data[i];
+ size_t n;
+ char *p = SvPV(cur->name, n);
+ OP *var, *cond;
+
+ cond = mkhvelem(aTHX_ param_spec->rest_hash, mkconstpv(aTHX_ p + 1, n - 1));
+
+ if (spec->flags & FLAG_CHECK_NARGS) {
+ OP *croak, *msg;
+
+ var = mkhvelem(aTHX_ param_spec->rest_hash, mkconstpv(aTHX_ p + 1, n - 1));
+ var = newUNOP(OP_DELETE, 0, var);
+
+ msg = mkconstsv(aTHX_ newSVpvf("In %"SVf": missing named parameter: %.*s", SVfARG(declarator), (int)(n - 1), p + 1));
+ croak = newCVREF(
+ OPf_WANT_SCALAR,
+ newGVOP(OP_GV, 0, gv_fetchpvs("Carp::croak", 0, SVt_PVCV))
+ );
+ croak = newUNOP(OP_ENTERSUB, OPf_STACKED, op_append_elem(OP_LIST, msg, croak));
+
+ cond = newUNOP(OP_EXISTS, 0, cond);
+
+ cond = newCONDOP(0, cond, var, croak);
+ }
+
+ var = my_var(
+ aTHX_
+ OPf_MOD | (OPpLVAL_INTRO << 8),
+ cur->padoff
+ );
+ var = newASSIGNOP(OPf_STACKED, var, 0, cond);
+
+ *prelude_sentinel = op_append_list(OP_LINESEQ, *prelude_sentinel, newSTATEOP(0, NULL, var));
+ }
+
+ for (i = 0, lim = param_spec->named_optional.used; i < lim; i++) {
+ ParamInit *cur = ¶m_spec->named_optional.data[i];
+ size_t n;
+ char *p = SvPV(cur->param.name, n);
+ OP *var, *cond;
+
+ var = mkhvelem(aTHX_ param_spec->rest_hash, mkconstpv(aTHX_ p + 1, n - 1));
+ var = newUNOP(OP_DELETE, 0, var);
+
+ cond = mkhvelem(aTHX_ param_spec->rest_hash, mkconstpv(aTHX_ p + 1, n - 1));
+ cond = newUNOP(OP_EXISTS, 0, cond);
+
+ cond = newCONDOP(0, cond, var, cur->init);
+ cur->init = NULL;
+
+ var = my_var(
+ aTHX_
+ OPf_MOD | (OPpLVAL_INTRO << 8),
+ cur->param.padoff
+ );
+ var = newASSIGNOP(OPf_STACKED, var, 0, cond);
+
+ *prelude_sentinel = op_append_list(OP_LINESEQ, *prelude_sentinel, newSTATEOP(0, NULL, var));
+ }
+
+ if (!param_spec->slurpy.name) {
+ if (spec->flags & FLAG_CHECK_NARGS) {
+ /* croak if %{rest} */
+ OP *croak, *cond, *keys, *msg;
+
+ keys = newUNOP(OP_KEYS, 0, my_var_g(aTHX_ OP_PADHV, 0, param_spec->rest_hash));
+ keys = newLISTOP(OP_SORT, 0, newOP(OP_PUSHMARK, 0), keys);
+ {
+ OP *first, *mid, *last;
+
+ last = keys;
+
+ mid = mkconstpvs(", ");
+ mid->op_sibling = last;
+
+ first = newOP(OP_PUSHMARK, 0);
+
+ keys = newLISTOP(OP_JOIN, 0, first, mid);
+ keys->op_targ = pad_alloc(OP_JOIN, SVs_PADTMP);
+ ((LISTOP *)keys)->op_last = last;
+ }
+
+ msg = mkconstsv(aTHX_ newSVpvf("In %"SVf": no such named parameter: ", SVfARG(declarator)));
+ msg = newBINOP(OP_CONCAT, 0, msg, keys);
+
+ croak = newCVREF(
+ OPf_WANT_SCALAR,
+ newGVOP(OP_GV, 0, gv_fetchpvs("Carp::croak", 0, SVt_PVCV))
+ );
+ croak = newUNOP(OP_ENTERSUB, OPf_STACKED, op_append_elem(OP_LIST, msg, croak));
+
+ cond = newUNOP(OP_KEYS, 0, my_var_g(aTHX_ OP_PADHV, 0, param_spec->rest_hash));
+ croak = newCONDOP(0, cond, croak, NULL);
+
+ *prelude_sentinel = op_append_list(OP_LINESEQ, *prelude_sentinel, newSTATEOP(0, NULL, croak));
+ } else {
+ OP *clear;
+
+ clear = newASSIGNOP(
+ OPf_STACKED,
+ my_var_g(aTHX_ OP_PADHV, 0, param_spec->rest_hash),
+ 0,
+ newNULLLIST()
+ );
+
+ *prelude_sentinel = op_append_list(OP_LINESEQ, *prelude_sentinel, newSTATEOP(0, NULL, clear));
+ }
+ } else if (param_spec->slurpy.padoff != param_spec->rest_hash) {
+ OP *var, *clear;
+
+ assert(SvPV_nolen(param_spec->slurpy.name)[0] == '@');
+
+ var = my_var_g(
+ aTHX_
+ OP_PADAV,
+ OPf_MOD | (OPpLVAL_INTRO << 8),
+ param_spec->slurpy.padoff
+ );
+
+ var = newASSIGNOP(OPf_STACKED, var, 0, my_var_g(aTHX_ OP_PADHV, 0, param_spec->rest_hash));
+
+ *prelude_sentinel = op_append_list(OP_LINESEQ, *prelude_sentinel, newSTATEOP(0, NULL, var));
+
+ clear = newASSIGNOP(
+ OPf_STACKED,
+ my_var_g(aTHX_ OP_PADHV, 0, param_spec->rest_hash),
+ 0,
+ newNULLLIST()
+ );
+
+ *prelude_sentinel = op_append_list(OP_LINESEQ, *prelude_sentinel, newSTATEOP(0, NULL, clear));
+ }
+ }
+
+ if (count_named_params(param_spec) && 0) {
int nameblock_ix;
OP *nameblock;
PADOFFSET vb, vc, vi, vk;
var = newASSIGNOP(OPf_STACKED, var, 0, newSVOP(OP_CONST, 0, newSViv(count_positional_params(param_spec))));
decl = op_append_list(OP_LINESEQ, decl, newSTATEOP(0, NULL, var));
- //S_intro_my(aTHX);
nameblock = op_append_list(OP_LINESEQ, nameblock, decl);
}
);
cur->init = NULL;
- cond = newUNOP(
- OP_NOT, OPf_SPECIAL,
- vc_is_str
+ cond = vc_is_str
? mkvecbits(aTHX_ vc, i)
: newBINOP(OP_BIT_AND, 0, my_var(aTHX_ 0, vc), newSVOP(OP_CONST, 0, newSVuv((UV)1 << i)))
- );
+ ;
- init = newCONDOP(0, cond, init, NULL);
+ init = newCONDOP(0, cond, NULL, init);
nameblock = op_append_list(OP_LINESEQ, nameblock, newSTATEOP(0, NULL, init));
}
like exception { name_1 }, qr/Not enough arguments/;
like exception { name_1 'n1' }, qr/Not enough arguments/;
like exception { name_1 'asdf' }, qr/Not enough arguments/;
-like exception { name_1 huh => 1 }, qr/\bnamed\b.+\bhuh\b/;
+like exception { name_1 n1 => 0, huh => 1 }, qr/\bnamed\b.+\bhuh\b/;
is_deeply name_1(n1 => undef), [undef, n1 => undef];
is_deeply name_1(n1 => 'a'), ['a', n1 => 'a'];
is_deeply name_1(n1 => 'a', n1 => 'b'), ['b', n1 => 'a', n1 => 'b'];
like exception { pos_1_name_1 42 }, qr/Not enough arguments/;
like exception { pos_1_name_1 42, 'n1' }, qr/Not enough arguments/;
like exception { pos_1_name_1 42, 'asdf' }, qr/Not enough arguments/;
-like exception { pos_1_name_1 42, huh => 1 }, qr/\bnamed\b.+\bhuh\b/;
+like exception { pos_1_name_1 42, n1 => 0, huh => 1 }, qr/\bnamed\b.+\bhuh\b/;
is_deeply pos_1_name_1(42, n1 => undef), [42, undef, 42, n1 => undef];
is_deeply pos_1_name_1(42, n1 => 'a'), [42, 'a', 42, n1 => 'a'];
is_deeply pos_1_name_1(42, n1 => 'a', n1 => 'b'), [42, 'b', 42, n1 => 'a', n1 => 'b'];
is_deeply name_1_slurp(n1 => 'a'), ['a', [], n1 => 'a'];
like exception { name_1_slurp n1 => 'a', 'n1' }, qr/Odd number/;
is_deeply name_1_slurp(n1 => 'a', foo => 'bar'), ['a', [foo => 'bar'], n1 => 'a', foo => 'bar'];
-is_deeply name_1_slurp(foo => 'bar', n1 => 'a', foo => 'quux'), ['a', [foo => 'bar', foo => 'quux'], foo => 'bar', n1 => 'a', foo => 'quux'];
+is_deeply name_1_slurp(foo => 'bar', n1 => 'a', foo => 'quux'), ['a', [foo => 'quux'], foo => 'bar', n1 => 'a', foo => 'quux'];
fun name_0_1_slurp(:$n1 = 'd', @rest) { [$n1, \@rest, @_] }
like exception { name_0_1_slurp n1 => 'a', 'n1' }, qr/Odd number/;
is_deeply name_0_1_slurp(a => 'b'), ['d', [a => 'b'], a => 'b'];
is_deeply name_0_1_slurp(n1 => 'a', foo => 'bar'), ['a', [foo => 'bar'], n1 => 'a', foo => 'bar'];
-is_deeply name_0_1_slurp(foo => 'bar', n1 => 'a', foo => 'quux'), ['a', [foo => 'bar', foo => 'quux'], foo => 'bar', n1 => 'a', foo => 'quux'];
+is_deeply name_0_1_slurp(foo => 'bar', n1 => 'a', foo => 'quux'), ['a', [foo => 'quux'], foo => 'bar', n1 => 'a', foo => 'quux'];
fun name_2(:$n1, :$n2) { [$n1, $n2, @_] }
like exception { name_1_2 }, qr/Not enough arguments/;
like exception { name_1_2 'n1' }, qr/Not enough arguments/;
like exception { name_1_2 'asdf' }, qr/Not enough arguments/;
-like exception { name_1_2 huh => 1 }, qr/\bnamed\b.+\bhuh\b/;
+like exception { name_1_2 n1 => 0, huh => 1 }, qr/\bnamed\b.+\bhuh\b/;
is_deeply name_1_2(n1 => 'a'), ['a', 'f', n1 => 'a'];
is_deeply name_1_2(n1 => 'a', n1 => 'b'), ['b', 'f', n1 => 'a', n1 => 'b'];
like exception { name_1_2 n2 => 'a' }, qr/missing named\b.+\bn1\b/;
is_deeply name_0_2(n1 => 'a', n2 => 42, n1 => undef), [undef, 42, n1 => 'a', n2 => 42, n1 => undef];
-fun pos_1_2_name_0_3_slurp($p1, $p2 = 'E', :$n1 = undef, :$n2 = 'A', :$n3 = 'F', @rest) { [$p1, $p2, $n1, $n2, $n3, \@rest, @_] }
+fun pos_1_2_name_0_3_slurp($p1, $p2 = 'E', :$n1 = undef, :$n2 = 'A', :$n3 = 'F', @rest) { [$p1, $p2, $n1, $n2, $n3, {@rest}, @_] }
like exception { pos_1_2_name_0_3_slurp }, qr/Not enough/;
-is_deeply pos_1_2_name_0_3_slurp('a'), ['a', 'E', undef, 'A', 'F', [], 'a'];
-is_deeply pos_1_2_name_0_3_slurp('a', 'b'), ['a', 'b', undef, 'A', 'F', [], 'a', 'b'];
+is_deeply pos_1_2_name_0_3_slurp('a'), ['a', 'E', undef, 'A', 'F', {}, 'a'];
+is_deeply pos_1_2_name_0_3_slurp('a', 'b'), ['a', 'b', undef, 'A', 'F', {}, 'a', 'b'];
like exception { pos_1_2_name_0_3_slurp 'a', 'b', 'c' }, qr/Odd number/;
-is_deeply pos_1_2_name_0_3_slurp('a', 'b', 'c', 'd'), ['a', 'b', undef, 'A', 'F', ['c', 'd'], 'a', 'b', 'c', 'd'];
+is_deeply pos_1_2_name_0_3_slurp('a', 'b', 'c', 'd'), ['a', 'b', undef, 'A', 'F', {'c', 'd'}, 'a', 'b', 'c', 'd'];
like exception { pos_1_2_name_0_3_slurp 'a', 'b', 'c', 'd', 'e' }, qr/Odd number/;
-is_deeply pos_1_2_name_0_3_slurp('a', 'b', 'c', 'd', 'e', 'f'), ['a', 'b', undef, 'A', 'F', ['c', 'd', 'e', 'f'], 'a', 'b', 'c', 'd', 'e', 'f'];
-is_deeply pos_1_2_name_0_3_slurp('a', 'b', n2 => 'c', n1 => 'd'), ['a', 'b', 'd', 'c', 'F', [], 'a', 'b', n2 => 'c', n1 => 'd'];
-is_deeply pos_1_2_name_0_3_slurp('a', 'b', n2 => 'c', beans => 'legume', n1 => 'd'), ['a', 'b', 'd', 'c', 'F', [beans => 'legume'], 'a', 'b', n2 => 'c', beans => 'legume', n1 => 'd'];
+is_deeply pos_1_2_name_0_3_slurp('a', 'b', 'c', 'd', 'e', 'f'), ['a', 'b', undef, 'A', 'F', {'c', 'd', 'e', 'f'}, 'a', 'b', 'c', 'd', 'e', 'f'];
+is_deeply pos_1_2_name_0_3_slurp('a', 'b', n2 => 'c', n1 => 'd'), ['a', 'b', 'd', 'c', 'F', {}, 'a', 'b', n2 => 'c', n1 => 'd'];
+is_deeply pos_1_2_name_0_3_slurp('a', 'b', n2 => 'c', beans => 'legume', n1 => 'd'), ['a', 'b', 'd', 'c', 'F', {beans => 'legume'}, 'a', 'b', n2 => 'c', beans => 'legume', n1 => 'd'];