—=head1 NAME
XS::Framework::Manual::SVAPI::Stash - XS::Framework Stash C++ class reference
=head1 Stash
=head2 Overview
The C<Stash> class extension of C<Hash> class, which provides convenient access
to perl symbol table as well as symbol resolution via C<call>, C<call_SUPER>
and C<call_next> methods.
Stash may be empty, i.e. contain C<NULL> C<SV*>.
=head2 Construction
static Stash root ()
Returns Perl's default stash.
Stash (std::nullptr_t = nullptr)
Creates an empty stash.
static Stash from_name (SV* fqn, I32 flags = 0)
Stash (const panda::string_view& package, I32 flags = 0)
Looks up for the specified fully-qualified package name and returns, may be empty,
C<Stash> object for the result. The C<flags> are additional parameters for lookup, e.g.
C<GV_ADD> will create new symbol table. See C<gv_stashpvn> in L<perlapi>.
Stash (SV* sv, bool policy = INCREMENT)
Stash (HV* sv, bool policy = INCREMENT)
Upgrades hash C<HV*>, which already refers to symbol table, or reference to it (C<SV*>)
into <Stash> object. If the supplied agrument is invalid, the exception will be
thrown. It is possible that the first agrument be C<NULL> or C<undef>, in that case
empty stash will be crated.
Copy and move-constructore are also available:
Stash (const Stash& oth)
Stash (const Hash& oth)
Stash (const Sv& oth)
Stash (Stash&& oth)
Stash (Hash&& oth)
Stash (Sv&& oth)
=head2 assignment operators
Stash& operator= (SV* val)
Stash& operator= (HV* val)
Stash& operator= (const Stash& oth)
Stash& operator= (Stash&& oth)
Stash& operator= (const Hash& oth)
Stash& operator= (Hash&& oth)
Stash& operator= (const Sv& oth)
Stash& operator= (Sv&& oth)
The assignment operators are complementaty to the constructors above. They
inherit behaviour from C<Hash>, including NULL-safety. The previously held
C<SV*> will be C<dec>-remented.
void set (HV* val)
The C<set> method directly assigns the value to the underlying C<SV*> in
the form of C<HV*>, I<bypassing all checks>. Use the method with caution.
=head2 element access
Glob fetch (const panda::string_view& key)
Glob at (const panda::string_view& key)
Glob operator[] (const panda::string_view& key)
op_proxy operator[] (const panda::string_view& key)
The first three methods return C<Glob> type via the C<key> string.
C<fetch> provides safe access to the elements, i.e. in case of absence of a key
empty C<Glob> will be returned. The C<at> method will throw error of the
specified C<key> is not found in the current symbol table. The
C<operator[] fetch> is the alias for C<fetch> method.
The non-const C<operator[]> allows in-place fast modification of underlying
element, i.e.
Stash stash = Stash("my::package", GV_ADD);
stash["PI"] = Simple(3.14);
All the methods above are NULL-safe; the assingment of empty stash leads
to thrown exception.
void store (const panda::string_view& key, SV* v)
void store (const panda::string_view& key, AV* v)
void store (const panda::string_view& key, HV* v)
void store (const panda::string_view& key, CV* v)
void store (const panda::string_view& key, GV* v)
void store (const panda::string_view& key, IO* v)
void store (const panda::string_view& key, const Sv& v)
void store (const panda::string_view& key, const Scalar& v)
void store (const panda::string_view& key, const Array& v)
void store (const panda::string_view& key, const Hash& v)
void store (const panda::string_view& key, const Sub& v)
void store (const panda::string_view& key, const Glob& v)
void store (const panda::string_view& key, const Io& v)
The NULL-safe C<store> method allows to inject the new value into the stash.
The exception will be thrown if the stash object is empty.
The following methods provide convenient access C<Stash> symbol
values, when the type is known:
Scalar scalar (const panda::string_view& name) const
Array array (const panda::string_view& name) const
Hash hash (const panda::string_view& name) const
Sub sub (const panda::string_view& name) const
Io io (const panda::string_view& name) const
void scalar (const panda::string_view& name, const Scalar& v)
void array (const panda::string_view& name, const Array& v)
void hash (const panda::string_view& name, const Hash& v)
void sub (const panda::string_view& name, const Sub& v)
void io (const panda::string_view& name, const Io& v)
The read-access is NULL-safe; the write-access (i.e assignment) on empty C<Stash>
throws exception. Usage example:
Stash stash = Stash("my::package");
auto pi = stash.scalar("pi");
stash.scalar("e", Simple(2.71)); // will throw if "my::package" is not known to Perl
=head2 method access
Sub method (const Sv& name) const
Sub method (const panda::string_view& name) const
Sub method_strict (const Sv& name) const
Sub method_strict (const panda::string_view& name) const
Sub super_method (const Sub& current) const
Sub super_method_strict (const Sub& current) const
Sub next_method (const Sub& current) const
Sub next_method_strict (const Sub& current) const
The method resolving can be performed either via C<panda::string_view> or C<Sv>
name. If a method name cannot be found, the empty C<Sub> is returned. To avoid
that the C<method_strict> should be invoked; if the method C<name> cannot be
found, then exception will be thrown.
The C<super_method> takes the existing C<Sub> and tries to find the corresponding
method in the B<parent> package of the current C<Stash>. It uses the resolution
order specified in the class (i.e. C<use mro 'c3'>). The C<next_method>
tries to find the next method using method resolution order, see L<mro>. The
C<_strict> version throw exception if nothing is found.
This are null-unsafe methods.
Usage example:
Stash stash = Stash("my::derived");
Sub m_child = stash.method("method");
Sub m_parent = stash.super_method(m_child);
m_parent.call();
=head2 method call
*depends* call (const Sv& name, Args&&...args) const
*depends* call (const panda::string_view& name, Args&&...args) const
*depends* call_SUPER (const Sub& context, Args&&...args) const
*depends* call_next (const Sub& context, Args&&...args) const
*depends* call_next_maybe (const Sub& context, Args&&...args) const
*depends* call_super (const Sub& context, Args&&...args) const
*depends* call_super_maybe (const Sub& context, Args&&...args) const
It is possible to invoke arbitrary method with arbitrary arguments if method
C<name> is known in a C<Stash>; if method is not found, then an exception will
be thrown. The C<call_SUPER> / C<call_super> / C<call_next> will lookup for
corresponding method in the parent or next class in the hierachy (see L<mro>).
The diffence between C<call_SUPER> / C<call_super> is how the parent method
is looked-up: either via classical DFS MRO resolution or via class-defined
resolution (i.e. C3 if 'use mro c3' or DFS otherwise).
The same methods with C<_maybe> prefix do exist: if the corresponding metthod
is not found, then empty result will be returned, i.e. no exception will be
thrown.
This are null-unsafe methods.
=head2 package name
panda::string_view name () const
HEK* name_hek () const
const Simple& name_sv () const
To know the name of the package, to which the current C<Stash> object points, the
C<name>, C<name_sv> and C<name_hek> methods can be used. For example:
Stash stash = Stash("my::package");
auto name = stash.name(); // returns "my::package"
If it is planned to let the package name be used in Perl in future, then prefer
to use C<name_sv> method.
panda::string_view effective_name () const
It is possible to have I<effective_name> of the current stash, if the stash
was aliased. See C<HvENAME> in L<perlapi>.
This are null-unsafe methods.
=head2 path()
panda::string path () const
Returns the file path for the current stash, i.e.
Stash s("A::B::C", GV_ADD);
s.path(); // returns A/B/C.pm
=head2 mark_as_loaded()
void mark_as_loaded (const Stash& source) const
void mark_as_loaded (const panda::string_view& source) const
Let the perl knows, where the current C<Stash> comes from, i.e. inserts into
the perl C<INC> variable the C<source> for the current C<Stash>. This is
useful, when writing multiple XS-bases packages in a single module.
L<XS::Framework> ships with a few useful macros, so, it is usually
used in the C<BOOT> section of the package like the following:
Stash(__PACKAGE__, GV_ADD).mark_as_loaded(__MODULE__);
The typical sympthom to use C<mark_as_loaded> is the following error:
Can't locate MyModule/MyClass.pm in @INC
=head2 inherit()
void inherit (const Stash& parent)
void inherit (const panda::string_view& parent)
Links the current symbol table as the descendant class for C<parent> C<Stash>.
In other words, it the following construct:
Stash child("MyPackage::Child"); // or, better Stash(__PACKAGE__, GV_ADD)
child.mark_as_loaded(__MODULE__);
Stash base("MyPackage::Base");
child.inherit(base);
is equivalent to perl code:
package MyPackage::Child;
use parent qw/MyPackage::Base/;
If the C<parent> package is defined as C<string_view>, it will be automatically
added to Perl via C<GV_ADD>.
The C<inherit> is NULL-safe method; the exception will be thrown if it is
invoked on empty C<Stash>.
=head2 isa()
bool isa (const panda::string_view& parent, U32 hash = 0, int flags = 0) const
bool isa (HEK* hek) const
bool isa (const Stash& parent) const
The C<isa> method returns C<true> if the current C<Stash> exactly matches C<parent>
C<Stash> or if the current C<Stash> is child class for the C<parent> C<Stash>.
The similar code in Perl is
child_CLASS->isa(parent_CLASS);
Under the hood the method uses C<hv_common> function (see C<perlapi>).
=head2 bless()
Object bless () const;
This method creates new C<Object>, which is blessed into to the current package
(C<Stash>).
Object bless (const Sv& what) const;
This C<bless> method version works somewhat similiar to the following Perl
construction
my $class = ...;
my $obj = ...;
return bless $obj => $class;
i.e. if C<what> is already an object, it is blessed into the C<Stash>,
otherwise new C<RV*> created from the C<what> argument, and the
blessed object returned.
=head2 add_const_sub()
void add_const_sub (const panda::string_view& name, const Sv& val);
Creates subroutine C<name> that returns constant C<val> eligible for compile-time inlining (like newCONSTSUB). C<val> is retained and made readonly.
C<val> can be either any C<Scalar> or <Array>. In latter case, const sub will return list containing array's values.
=head1 SEE ALSO
L<XS::Framework>
L<XS::Framework::Manual::SVAPI>
L<XS::Framework::Manual::SVAPI::Sv>
L<XS::Framework::Manual::SVAPI::Hash>
=cut