The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

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.

SEE ALSO

XS::Framework

XS::Framework::Manual::SVAPI

XS::Framework::Manual::SVAPI::Sv

XS::Framework::Manual::SVAPI::Hash