NAME
XS::Framework::Manual::SVAPI::Stash - XS::Framework Stash C++ class reference
Stash
Overview
The Stash
class extension of Hash
class, which provides convenient access to perl symbol table as well as symbol resolution via call
, call_SUPER
and call_next
methods.
Stash may be empty, i.e. contain NULL
SV*
.
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, Stash
object for the result. The flags
are additional parameters for lookup, e.g. GV_ADD
will create new symbol table. See gv_stashpvn
in perlapi.
Stash (SV* sv, bool policy = INCREMENT)
Stash (HV* sv, bool policy = INCREMENT)
Upgrades hash HV*
, which already refers to symbol table, or reference to it (SV*
) into <Stash> object. If the supplied agrument is invalid, the exception will be thrown. It is possible that the first agrument be NULL
or 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)
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 Hash
, including NULL-safety. The previously held SV*
will be dec
-remented.
void set (HV* val)
The set
method directly assigns the value to the underlying SV*
in the form of HV*
, bypassing all checks. Use the method with caution.
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 Glob
type via the key
string. fetch
provides safe access to the elements, i.e. in case of absence of a key empty Glob
will be returned. The at
method will throw error of the specified key
is not found in the current symbol table. The operator[] fetch
is the alias for fetch
method.
The non-const 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 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 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 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
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 panda::string_view
or Sv
name. If a method name cannot be found, the empty Sub
is returned. To avoid that the method_strict
should be invoked; if the method name
cannot be found, then exception will be thrown.
The super_method
takes the existing Sub
and tries to find the corresponding method in the parent package of the current Stash
. It uses the resolution order specified in the class (i.e. use mro 'c3'
). The next_method
tries to find the next method using method resolution order, see mro. The _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();
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 name
is known in a Stash
; if method is not found, then an exception will be thrown. The call_SUPER
/ call_super
/ call_next
will lookup for corresponding method in the parent or next class in the hierachy (see mro).
The diffence between call_SUPER
/ 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 _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.
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 Stash
object points, the name
, name_sv
and 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 name_sv
method.
panda::string_view effective_name () const
It is possible to have effective_name of the current stash, if the stash was aliased. See HvENAME
in perlapi.
This are null-unsafe methods.
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
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 Stash
comes from, i.e. inserts into the perl INC
variable the source
for the current Stash
. This is useful, when writing multiple XS-bases packages in a single module. XS::Framework ships with a few useful macros, so, it is usually used in the BOOT
section of the package like the following:
Stash(__PACKAGE__, GV_ADD).mark_as_loaded(__MODULE__);
The typical sympthom to use mark_as_loaded
is the following error:
Can't locate MyModule/MyClass.pm in @INC
inherit()
void inherit (const Stash& parent)
void inherit (const panda::string_view& parent)
Links the current symbol table as the descendant class for parent
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 parent
package is defined as string_view
, it will be automatically added to Perl via GV_ADD
.
The inherit
is NULL-safe method; the exception will be thrown if it is invoked on empty Stash
.
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 isa
method returns true
if the current Stash
exactly matches parent
Stash
or if the current Stash
is child class for the parent
Stash
. The similar code in Perl is
child_CLASS->isa(parent_CLASS);
Under the hood the method uses hv_common
function (see perlapi
).
bless()
Object bless () const;
This method creates new Object
, which is blessed into to the current package (Stash
).
Object bless (const Sv& what) const;
This bless
method version works somewhat similiar to the following Perl construction
my $class = ...;
my $obj = ...;
return bless $obj => $class;
i.e. if what
is already an object, it is blessed into the Stash
, otherwise new RV*
created from the what
argument, and the blessed object returned.
add_const_sub()
void add_const_sub (const panda::string_view& name, const Sv& val);
Creates subroutine name
that returns constant val
eligible for compile-time inlining (like newCONSTSUB). val
is retained and made readonly.
val
can be either any Scalar
or <Array>. In latter case, const sub will return list containing array's values.