}
}
+void
+get_all_symbols(self, vartype=VAR_NONE)
+ SV *self
+ vartype_t vartype
+ PREINIT:
+ HV *namespace, *ret;
+ SV *val;
+ char *key;
+ I32 len;
+ PPCODE:
+ namespace = _get_namespace(self);
+ ret = newHV();
+
+ hv_iterinit(namespace);
+ while ((val = hv_iternextsv(namespace, &key, &len))) {
+ GV *gv = (GV*)val;
+
+ if (!isGV(gv))
+ _expand_glob(self, key);
+
+ switch (vartype) {
+ case VAR_SCALAR:
+ if (GvSVOK(val))
+ hv_store(ret, key, len, newRV_inc(GvSV(gv)), 0);
+ break;
+ case VAR_ARRAY:
+ if (GvAVOK(val))
+ hv_store(ret, key, len, newRV_inc((SV*)GvAV(gv)), 0);
+ break;
+ case VAR_HASH:
+ if (GvHVOK(val))
+ hv_store(ret, key, len, newRV_inc((SV*)GvHV(gv)), 0);
+ break;
+ case VAR_CODE:
+ if (GvCVOK(val))
+ hv_store(ret, key, len, newRV_inc((SV*)GvCV(gv)), 0);
+ break;
+ case VAR_IO:
+ if (GvIOOK(val))
+ hv_store(ret, key, len, newRV_inc((SV*)GvIO(gv)), 0);
+ break;
+ case VAR_NONE:
+ hv_store(ret, key, len, SvREFCNT_inc_simple_NN(val), 0);
+ break;
+ }
+ }
+
+ mPUSHs(newRV_noinc((SV*)ret));
+
BOOT:
{
name_key = newSVpvs("name");
ok(defined(*{"Foo::foo"}{ARRAY}), '... the @foo slot has NOT been removed');
}
+{
+ my $syms = $foo_stash->get_all_symbols;
+ is_deeply(
+ [ sort keys %{ $syms } ],
+ [ sort $foo_stash->list_all_symbols ],
+ '... the fetched symbols are the same as the listed ones'
+ );
+}
+
+{
+ my $syms = $foo_stash->get_all_symbols('CODE');
+
+ is_deeply(
+ [ sort keys %{ $syms } ],
+ [ sort $foo_stash->list_all_symbols('CODE') ],
+ '... the fetched symbols are the same as the listed ones'
+ );
+
+ foreach my $symbol (keys %{ $syms }) {
+ is($syms->{$symbol}, $foo_stash->get_symbol('&' . $symbol), '... got the right symbol');
+ }
+}
+
+{
+ $foo_stash->add_symbol('%zork');
+
+ my $syms = $foo_stash->get_all_symbols('HASH');
+
+ is_deeply(
+ [ sort keys %{ $syms } ],
+ [ sort $foo_stash->list_all_symbols('HASH') ],
+ '... the fetched symbols are the same as the listed ones'
+ );
+
+ foreach my $symbol (keys %{ $syms }) {
+ is($syms->{$symbol}, $foo_stash->get_symbol('%' . $symbol), '... got the right symbol');
+ }
+
+ no warnings 'once';
+ is_deeply(
+ $syms,
+ { zork => \%Foo::zork },
+ "got the right ones",
+ );
+}
+
# check some errors
like(exception {
} "list_all_symbols doesn't leak";
}
+{
+ package Blah;
+ use constant 'baz';
+}
+
+{
+ my $foo = Package::Stash->new('Foo');
+ my $blah = Package::Stash->new('Blah');
+ no_leaks_ok {
+ $foo->get_all_symbols;
+ $foo->get_all_symbols('SCALAR');
+ $foo->get_all_symbols('CODE');
+ $blah->get_all_symbols('CODE');
+ } "list_all_symbols doesn't leak";
+}
+
# mimic CMOP::create_anon_class
{
local $TODO = $] < 5.010 ? "deleting stashes is inherently leaky on 5.8"