pod::Pr...nternals(3)
๐ธ NAME ๐ธ
Prima::internals โ Prima internal architecture. This is the pod::Pr...nternals(3) page from User Contributed Perl Documentation, and yes bestie, you are exactly where you need to be ๐
๐ DESCRIPTION ๐
Okay so this document describes the internal structures of the Prima toolkit, its loading considerations, object and class representation, and C coding style. It's giving backstage-lore energy, and we are seated.
๐ฑ Bootstrap ๐ฑ
๐ Initializing ๐
From the point of view of a perl script, Prima is no more but an average module that uses DynaLoader. As the use Prima code gets executed, the bootstrap procedure boot_Prima() is called. This procedure initializes all internal structures and built-in Prima classes. It also initializes all system-dependent structures, calling window_subsystem_init(). After that point, the Prima module is ready to use. All wrapping code for built-in functionality that can be seen from perl is in two modules โ Prima::Const and Prima::Classes.
๐จ Constants ๐จ
Prima defines a lot of constants for different purposes (e.g. colors, font styles,0 etc). Prima does not follow perl naming conventions here, for the sake of simplicity. It is (arguably) easier to write cl::White rather than Prima::cl::White. As perl constants are functions to be called once (that means that a constant's value is not defined until it is used first), Prima registers these functions during the boot_Prima stage. As soon as perl code tries to get a constant's value, an AUTOLOAD function is called, which is banded inside Prima::Const. Constants are widely used both in C and perl code and are defined in apricot.h in such a way so that perl constant definitions come along with the C ones. As an example file event constants set is described here.
apricot.h:
#define FE(const_name) CONSTANT(fe,const_name)
START_TABLE(fe,UV)
#define feRead 1
FE(Read)
#define feWrite 2
FE(Write)
#define feException 4
FE(Exception)
END_TABLE(fe,UV)
#undef FE
Const.pm:
package fe; *AUTOLOAD = \&Prima::Const::AUTOLOAD;
This code creates a structure filled with UVs (unsigned integers) and declares a register_fe_constants() function, which should be called at the boot_Prima stage. This way feRead becomes the C analog to the fe::Read in perl.
๐งฌ Classes and methods ๐งฌ
๐น๏ธ Virtual method tables ๐น๏ธ
Prima implementation of classes uses virtual method tables, or VMTs, to make the classes inheritable and their methods overridable. The VMTs are usual C structs that contain pointers to functions. A set of these functions represents a class. This chapter is not about OO programming โ you have to find a good book on it if you are not familiar with the OO concepts โ but in short, because Prima is written in C, not in C++, it uses its own classes and objects implementation, so all object syntax is devised from scratch.
The built-in classes already contain all the information needed for method overloading, but when a new class is derived from an existing one, a new VMT has to be created as well. The actual sub-classing is performed inside build_dynamic_vmt() and build_static_vmt(). The gimme_the_vmt() function creates a new VMT instance on the fly and caches the result for every new class that is derived from a Prima built-in class.
๐ C to Perl and Perl to C calling routines ๐
The majority of Prima methods are written in C using XS perl routines, which represent a natural (from a perl programmer's view) way of C-to-Perl communication. The perlguts manpage describes these functions and macros.
Note: Do not mix XS calls with the XS language (perlxs manpage) โ the latter is a meta-language for simplification of coding tasks and is not used in the Prima implementation.
It was decided not to code every function with XS calls, but instead use special wrapper functions (also called "thunks") for every function that is called from within perl. Thunks are generated automatically by the gencls tool (prima-gencls manpage), and the typical Prima method consists of three functions, two of which are thunks.
The first function, say Class_init(char*), would initialize a class (for example). It is written fully in C, so to be called from perl code a registration step must be taken for the second function, Class_init_FROMPERL(), that would look like this:
newXS( "Prima::Class::init", Class_init_FROMPERL, "Prima::Class");
Class_init_FROMPERL() is the first thunk, that translates the parameters passed from perl to C and the result back from the C function to perl. This step is almost fully automatized, so one never bothers about writing the XS code, the gencls utility creates the thunks code automatically.
Many C methods are called from within Prima C code using VMTs, but it is possible to override these methods from the perl code too. The actions for such a situation when a function is called from C but is an overridden method therefore must be taken. On that occasion, the third function Class_init_REDEFINED() is declared. Its task is a reverse from Class_init_FROMPERL() โ it conveys all C parameters to perl and returns values from a perl function back to C. This thunk is also generated automatically by the gencls tool.
As one can notice, only basic data types can be converted between C and perl, and at some point, automated routines do not help. In such a situation data conversion code is written manually and is included in core C files. In the class declaration files these methods are prepended with the 'public' or 'weird' modifiers, while methods with no special data handling need to use the 'method' or 'static' modifiers.
Note: functions that are not allowed to be seen from perl should have the 'c_only' modifier, and do not need the thunk wrapping. These functions can nevertheless be overridden from C.
๐ Built-in classes ๐
Prima defines the following built-in classes: (in hierarchy order)
Object
Component
AbstractMenu
AccelTable
Menu
Popup
Clipboard
Drawable
DeviceBitmap
Printer
Image
Icon
File
Region
Timer
Widget
Application
Window
These classes can be seen from perl with Prima:: prefix. Along with these, the Utils class is defined in a special way. Its only difference is that it cannot be used as a prototype for an object, and used merely as a package that binds functions. Classes that are not intended to be an object prototype are marked with the 'package' prefix while the other classes are marked with the 'object' prefix (see prima-gencls manpage).
๐ธ Objects ๐ธ
Okay bestie, listen up โ this chapter is only about Prima::Object descendants. Pure perl objects? Not invited to this party, they're not interesting here. So whenever we say "object" from now on, we mean a Prima::Object descendant object, periodt. And here's the vibe: Prima uses blessed hashes as its objects. That's the whole aesthetic. ๐
โจ Creation โจ
So like, every built-in object class and their descendants can totally be used to create objects with perl semantics. Perl objects get made by calling bless() โ but ngl, that alone is not enough to create a Prima object. That's why every Prima::Object descendant class comes equipped with the create() method, which allocates the object instance and calls bless() itself. Iconic behavior honestly.
The parameters you pass to create() get formed into a hash and handed over to the init() method, which โ surprise โ also exists on every object. Quick heads up though: even though the perl-coded init() returns the hash, it is not seen in C code. This is a special consideration for methods that have 'HV * profile' as a last parameter in their class declaration. The corresponding thunk copies the hash content back to the perl stack using the parse_hv() and push_hv() functions. Slay.
Creating objects from perl looks like this, bestie:
$obj = Prima::SampleObject-> create(
name => "Sample",
index => 10,
);
And from C:
Handle obj;
HV * profile = newHV();
pset_c( name, "Sample");
pset_i( index, 10);
obj = Object_create("SampleObject", profile);
sv_free(( SV*) profile);
Or even, if you're feeling spicy:
create_object("SampleObject", "si",
"name", "Sample",
"index", 10
);
The convenience pset_XX macros assign a value of type XX to the hash key given as the first parameter, into a hash variable named profile. So pset_i works with integers, pset_c with strings, etc. Easy. ๐
๐ฆ Destruction ๐ฆ
Just like create(), every object class has a destroy() method. You can destroy an object from perl:
$obj-> destroy
Or from C:
Object_destroy( obj);
An object can also be automatically destroyed when its reference count reaches 0. But โ ๏ธ heads up โ auto destruction would never happen if the object's reference count isn't lowered after its creation. So this line right here:
--SvREFCNT( SvRV( PAnyObject(object)-> mate));
is required if the object is to be returned to perl. If you don't call it, the object can still be destroyed explicitly, but its reference would still live โ resulting in a memory leak problem. ๐ญ Not the vibe.
For your own user code, it's totally sufficient to overload done() and/or cleanup(), or just the onDestroy notification. But it is highly recommended to avoid overloading the destroy() method since it can be called in a re-entrant fashion. And when you overload done(), be prepared that it may be called inside init() โ so deal with the semi-initialized object, bestie. ๐ซถ
๐ Data instance ๐
All Prima objects are blessed hashes, and the hash key __CMATE__ holds a C pointer to memory occupied by a C data instance, aka a "mate". It keeps all object variables and a pointer to the VMT. Every object has its own copy of the data instance, but the VMTs can be shared. To reach the C data instance you use the gimme_the_mate() function. As its first argument it accepts a scalar (SV*), which is expected to be a reference to a hash, and it returns the C data instance if the scalar is a Prima object. Iconic little accessor. โจ
๐ Object life stages ๐
There are several steps โ "stages" โ in every object's life cycle. Every stage is mirrored into the PObject(self)-> stage integer variable, which can be one of these csXXX constants:
csConstructingโ the object is in this initial stage untilcreate()is finished. Right afterinit()is completed, thesetup()method is called. ๐ฃcsNormalโ aftercreate()is finished and beforedestroy()starts. If an object is in eithercsNormalorcsConstructingstage, the result of theObject_alive()method is non-zero. Alive and thriving.csDestroyingโ thedestroy()started. This stage runs thecleanup()and thedone()methods.csFrozenโcleanup()started.csFinalizingโdone()started.csDeadโdestroy()finished. ๐ Rip.
๐ง Coding techniques ๐ง
๐ Accessing object data ๐
C coding in Prima has no specific conventions, except when you're coding an object method. The object syntax for accessing the object's data instance is though fairly straightforward. For example, accessing the component field called 'name' can be done in several ways:
((PComponent) self)-> name; // classic C
PComponent(self)-> name; // using PComponent() macro from apricot.h
var-> name; // using local var() macro
Object methods could be called in several ways too:
(((PComponent) self)-> self)-> get_name( self); // classic C
CComponent(self)-> get_name( self); // using CComponent() macro from apricot.h
my-> get_name( self); // using local my() macro
The calling of methods via the object's VMTs is preferred, compared to the direct call of Component_get_name(), primarily because get_name() is a method that can be overridden in the user code. So like, don't hardcode it, bestie. ๐
๐ Calling perl code ๐
The call_perl_indirect() function accepts an object, a name of the method to be called, an argument format string, and an argument list. It has several wrappers for ease of use, which are:
call_perl( Handle self, char * method, char * format, ...)
sv_call_perl( SV * object, char * method, char * format, ...)
cv_call_perl( SV * object, SV * code_reference, char * format, ...)
Each character of the format string represents the type of the corresponding argument, using these characters to encode types:
'i' - integer
's' - char *
'n' - float
'H' - Handle
'S' - SV *
'P' - Point
'R' - Rect
The format string can be prepended with the '<' character, in which case an SV * scalar value is returned โ always scalar, even if the code returns nothing or an rray (that's a typo situation in the original, we're keeping it fr fr). The caller is responsible for freeing the returned value. ๐
๐ฅ Exceptions ๐ฅ
As described in the perlguts manpage, the G_EVAL flag is used in perl_call_sv() and perl_call_method() to indicate that an eventual exception should never be propagated automatically. The caller checks if the exception took place by evaluating the
SvTRUE( GvSV( errgv))
statement. It is guaranteed to be false if there was raised no exception. In some situations though โ namely when no perl_call_* functions are called, or an error value is already assigned before calling code โ there's a wrapping technique that keeps the eventual previous error message. Such code may look like this:
dG_EVAL_ARGS; // define arguments
....
OPEN_G_EVAL; // open brackets
// call code
perl_call_method( ... | G_EVAL); // G_EVAL is necessary
if ( SvTRUE( GvSV( errgv)) {
CLOSE_G_EVAL; // close brackets
croak( SvPV_nolen( GvSV( errgv)));// propagate exception
// no code is executed after croak
}
CLOSE_G_EVAL; // close brackets
...
This technique provides a workaround to a "false alarm" situation if SvTRUE( GvSV( errgv)) is already true before perl_call_method(). Lowkey a lifesaver. ๐ญ
๐ Object protection ๐
After the object destroy stage is completed, it's possible that the object's data instance is gone โ and even a simple stage check might cause a segmentation fault. ๐ To avoid this, the bracketing functions protect_object() and unprotect_object() are used. protect_object() increments the reference count to the object instance, thus delaying its freeing until the decrementing unprotect_object() is called.
All C code that references an object must check its stage after every routine that may potentially switch to perl code, because the object might be destroyed inside the call. A typical code example would be like this:
int handle_object(Handle object) {
int stage;
protect_object( object);
// call some perl code
perl_call_method( object, "test", ...);
stage = PObject(object)-> stage;
unprotect_object( object);
if ( stage != csNormal) return 0;
// proceed with the object
...
return 1;
}
Usually C code doesn't need to check the object stage before the call to perl is made, because the gimme_the_mate() function returns NULL when the object's stage is csDead, and the majority of Prima C code is prepended with this call โ thus rejecting invalid references at an early stage. And if you do want to get the C mate for objects that are in the csDead stage, use the gimme_the_real_mate() function instead. ๐ซถ
๐ธ init ๐ธ
Object's method init() is responsible for setting all its initial properties to the given values. However โ and this is the important bit โ all code executed inside init() must be aware that the object's stage is csConstructing. init() consists of two parts: calling of ancestor's init() and setting the properties. Examples are many in both C and perl code, but in short it looks like this:
void
Class_init( Handle self, HV * profile)
{
inherited init( self, profile);
my-> set_index( pget_i( index));
my-> set_name( pget_c( name));
}
The pget_XX macros call croak() if the profile key is not present in the profile, but the mechanism guarantees that all keys listed in profile_default() are conveyed to the init(). For explicit checking of key presence you use the pexists() macro, and the pdelete() macro is used for key deletion โ although it's not recommended to use pdelete() inside init(). You've been warned bestie. ๐
โญ Object creation and returning โญ
As described in the previous sections, there are some precautions to take into account when an object is created inside C code. A piece of real code from DeviceBitmap.c serves as our example:
static
Handle xdup( Handle self, char * className)
{
Handle h;
Point s;
PDrawable i;
// allocate a parameters hash
HV * profile = newHV();
// set all necessary arguments
pset_H( owner, var-> owner);
pset_i( width, var-> w);
pset_i( height, var-> h);
pset_i( type, (var-> type == dbtBitmap) ? imBW : imRGB);
// create object
h = Object_create( className, profile);
// free profile, do not need it anymore
sv_free(( SV *) profile);
i = ( PDrawable) h;
s = i-> self-> get_size( h);
i-> self-> begin_paint( h);
i-> self-> put_image_indirect( h, self, 0, 0, 0, 0, s.x, s.y, s.x, s.y, ropCopyPut);
i-> self-> end_paint( h);
// decrement reference count
--SvREFCNT( SvRV( i-> mate));
return h;
}
And that's the whole flow โ allocate, create, clean up the profile, do your thing, then decrement the reference count before handing it back. Chef's kiss. ๐โจ
okay so real talk about the xdup() note: every bit of code that would use this xdup() has to bump up and then down the object's reference count whenever some perl functions are gonna run before the object gets returned to perl. If you skip that, it might literally get destroyed in the middle of execution ๐ญ
Handle x = xdup( self, "Prima::Image");
++SvREFCNT( SvRV( PAnyObject(x)-> mate)); // Code without these
CImage( x)-> type( x, imbpp1);
--SvREFCNT( SvRV( PAnyObject(x)-> mate)); // brackets is unsafe
return x;
bestie, those++/--lines are not decorative. they're the whole safety vibe check ๐
๐ Attaching objects ๐
A freshly created object returned from C gets destroyed right away by perl's garbage cleaning mechanism, unless the object value is assigned to a scalar, for example.
So this:
$c = Prima::Object-> create();
and this:
Prima::Object-> create;
have different results. But for some classes โ namely Widget and its descendants, and also Timer, AbstractMenu, Printer, and Clipboard โ the code above would have the same result: the objects would not be killed. That's because these objects call the Component_attach() method during the init-stage, automatically increasing their reference count. Component_attach() and its reverse Component_detach() keep a list of objects that are attributed to each other. An object can be attached to more than one object at a time, but it cannot be attached more than once to another object.
๐ฆ Notifications ๐ฆ
All descendants of the Prima::Component class are equipped with a mechanism that lets user callback routines get called when corresponding events occur. A very similar mechanism is used typically everywhere in event-driven programming. Component_notify() is used to call the user notifications; its format string has the same format as accepted by perl_call_indirect(). The only difference is that it always has to be prepended with '<s' โ this way the call success flag can be returned โ and the first parameter must be the name of the notification.
Component_notify( self, "<sH", "Paint", self);
Component_notify( self, "<sPii", "MouseDown", self, point, int, int);
The notification mechanism keeps another reference list, similar to the attach-detach mechanism, so that notifications can be attributed to different objects. Objects entering the list don't get their reference counter changed.
๐ธ Multi-property setting ๐ธ
The Prima::Object method set() is designed to assign several properties at once. Sometimes it's way more convenient to write:
$c-> set( index => 10, name => "Sample" );
than to invoke several methods one by one. The set() method executes these calls itself, but for performance reasons it's possible to overload this method and code special conditions for the mult-assignment. As an example, here's Prima::Image type conversion code using this technique:
void
Image_set( Handle self, HV * profile)
{
...
if ( pexist( type))
{
int newType = pget_i( type);
if ( !itype_supported( newType))
warn("Invalid image type requested (%08x) in Image::set_type",
newType);
else
if ( !opt_InPaint)
my-> reset( self, newType, pexist( palette) ?
pget_sv( palette) : my->get_palette( self));
pdelete( palette);
pdelete( type);
}
...
inherited set ( self, profile);
}
Here, if the type conversion is performed along with the palette change, some efficiency is gained by supplying both the 'type' and 'palette' parameters at once. Moreover, because the ordering of the fields is not determined by default โ although that is done by supplying the '__ORDER__' hash key to set() } โ it can easily be discovered that:
$image-> type( $a);
$image-> palette( $b);
and:
$image-> palette( $b);
$image-> type( $a);
produce different results. Therefore the only solution here is to code Class_set() explicitly.
If it is desired to specify the exact order of how atomic properties have to be called, the __ORDER__ anonymous array has to be added to the set() parameters.
$image-> set(
owner => $xxx,
type => 24,
__ORDER__ => [qw( type owner)],
);
โจ API reference โจ
Okay bestie, this is the low-level lore drop ๐ญ โ all the C-side variables and functions that make Prima do its thing. No cap, every signature is here exactly as it appears. ๐
๐งฌ Variables ๐งฌ
primaObjects,PHashโ hash with all prima objects, where keys are their data instances. ๐application,Handleโ pointer to the application. There can be only oneApplicationinstance at a time, or none at all. ๐
๐ ๏ธ Macros and functions ๐ ๏ธ
dG_EVAL_ARGSโ defines a variable for$@value storage. ๐พOPEN_G_EVAL,CLOSE_G_EVALโ brackets for exception catching. ๐ชbuild_static_vmtโ signature:Bool(void * vmt). Caches pre-built VMT for further use. ๐งbuild_dynamic_vmtโ signature:Bool( void * vmt, char * ancestorName, int ancestorVmtSize). Creates a subclass fromvmtand caches the result underancestorNamekey. ๐งฌgimme_the_vmtโ signature:PVMT( const char *className);. Returns the VMT pointer associated with class by name. ๐gimme_the_mateโ signature:Handle( SV * perlObject). Returns a C pointer to an object, ifperlObjectis a reference to a Prima object. ReturnsNULL_HANDLEif the object stage iscsDead. ๐gimme_the_real_mateโ signature:Handle( SV * perlObject). Returns a C pointer to an object, ifperlObjectis a reference to a Prima object. Same asgimme_the_mate, but does not check for the object stage. ๐alloc1โ signature:alloc1(type). To be used instead(type*)(malloc(sizeof(type)). ๐งฑallocnโ signature:allocn(type,n). To be used instead(type*)(malloc((n)*sizeof(type)). ๐งฑalloc1zโ same asalloc1but fills the allocated memory with zeros. 0๏ธโฃallocnzโ same asallocnbut fills the allocated memory with zeros. 0๏ธโฃprima_malloczโ same asmalloc()but fills the allocated memory with zeros. 0๏ธโฃprima_hash_createโ signature:PHash(void). Creates an empty hash. ๐๏ธprima_hash_destroyโ signature:void(PHash self, Bool killAll);. Destroys a hash. IfkillAllis true, assumes that every value in the hash is a dynamic memory pointer and callsfree()on each. ๐ฅprima_hash_fetchโ signature:void*( PHash self, const void *key, int keyLen);. Returns the pointer to a value, if found,NULLotherwise. ๐prima_hash_deleteโ signature:void*( PHash self, const void *key, int keyLen, Bool kill);. Deletes the hash key and returns the associated value. If thekillargument is true, callsfree()on the value and returnsNULL. ๐๏ธprima_hash_storeโ signature:void( PHash self, const void *key, int keyLen, void *val);. Stores a new value into hash. If the key is already present, the old value is overwritten. ๐ฅprima_hash_countโ signature:int(PHash self). Returns the number of keys in the hash. ๐ขprima_hash_first_thatโ signature:void * ( PHash self, void *action, void *params, int *pKeyLen, void **pKey);. Enumerates all hash entries, callingactionprocedure on each. If theactionprocedure returns true, enumeration stops and the last processed value is returned. OtherwiseNULLis returned.actionhas to be a function declared as:
Bool action_callback( void * value, int keyLen, void * key, void * params);
The params argument is a pointer to arbitrary user data. ๐ง
kind_ofโ signature:Bool( Handle object, void *cls);. Returns true, if the object is an exemplar of classclsor its descendant. ๐PERL_CALL_METHOD,PERL_CALL_PVโ to be used instead ofperl_call_methodandperl_call_pv, (see theperlgutsmanpage). These functions should be used to code a workaround of the perl bug which emerges when theG_EVALflag is combined withG_SCALAR. ๐evalโ signature:SV *( char *string). Simplifiedperl_eval_pv()call. ๐ชsv_query_methodโ signature:CV * ( SV * object, char *methodName, Bool cacheIt);. Returns a perl pointer to a method searched by the perl object and the name. IfcacheItis true, caches the result of the hierarchy traversal for speedup. โกquery_methodโ signature:CV * ( Handle object, char *methodName, Bool cacheIt);. Returns a perl pointer to a method searched by the C object and the name. IfcacheItis true, caches the hierarchy traverse result for a speedup. โกcall_perl_indirectโ signature:
SV * ( Handle self, char *subName, const char *format, Bool cdecl,
Bool coderef, va_list params);
The main core function for calling Prima methods. Is used by the following three functions, but is never called directly. The format is described in the "Calling perl code" section. ๐ ๏ธ
call_perlโ signature:SV * ( Handle self, char *subName, const char *format, ...);. Calls thesubNamemethod on a C object. ๐sv_call_perlโ signature:SV * ( SV * mate, char *subName, const char *format, ...);. Calls thesubNamemethod on a perl object. ๐cv_call_perlโ signature:SV * ( SV * mate, Sv * coderef, const char *format, ...);. Calls arbitrary perl code with aSV mateas the first parameter. Used in notifications mechanism. ๐ฃObject_createโ signature:Handle( char * className, HV * profile);. Creates an exemplar ofclassNameclass with parameters in theprofilehash. Never returnsNULL_HANDLE, throws an exception instead. ๐๏ธcreate_objectโ signature:void*( const char *objClass, const char *format, ...);. A convenience wrapper toObject_create. Uses the format specification that is described in the section"Calling perl code"above. ๐create_instanceโ signature:Handle( const char * className). Convenience call to"Object_create"with parameters in hash'profile'. ๐Object_destroyโ signature:void( Handle self);. Destroys an object. One of the few Prima functions that can be called in the re-entrant fashion. ๐Object_aliveโ signature:void( Handle self);. Returns non-zero if the object is alive, 0 otherwise. In particular, returns 1 if the object's stage iscsNormaland 2 if it iscsConstructing. Has virtually no use in C, only used in perl code. ๐protect_objectโ signature:void( Handle obj);. Protects the object data from deletion afterObject_destroy()is called. Can be called several times on an object. IncrementsObject.protectCount. ๐ก๏ธunprotect_objectโ signature:void( Handle obj);. Frees theobjectdatapointerafterObject.protectCounthits zero. Can be called several times on an object. ๐parse_hvโ signature:HV *( I32 ax, SV **sp, I32 items, SV **mark, int expected, const char *methodName);. Transfers arguments in perl stack to a newly createdHVand returns it. ๐ฆpush_hvโ signature:void ( I32 ax, SV **sp, I32 items, SV **mark, int callerReturns, HV *hv);. Puts allhvcontents back into perl stack. ๐คpush_hv_for_REDEFINEDโ signature:SV **( SV **sp, HV *hv);. Putshvcontent as arguments to perl code to be called. ๐จpop_hv_for_REDEFINEDโ signature:int ( SV **sp, int count, HV *hv, int shouldBe);. Reads the result of the executed perl code and stores it into theHVhash. ๐ฅpexistโ signature:Bool(char*key). Returns true if a key is present in the hash'profile'. โpdeleteโ signature:void(char*key). Deletes a key in the hash'profile'. โpget_sv,pget_i,pget_f,pget_c,pget_H,pget_Bโ signature:TYPE(char*key). Returns a value of one of the types supported (SV*,int,float,char*,HandleorBool) that is associated with a key in the hash'profile'. Callscroak()if the key is not present. ๐คpset_sv,pset_i,pset_f,pset_c,pset_Hโ signature:void( char*key, TYPE value). Assignsvalueto a key in hash'profile'and increments reference count to a newly created scalar. ๐งฎpset_bโ signature:void( char*key, void* data, int length). Assigns binary data to a key in the hash'profile'and increments the reference counter for the newly created scalar. ๐งฌpset_sv_noincโ signature:void(char* key, SV * sv). Assigns a scalar value to a key in the hash'profile'without incrementing the reference counter. ๐ซduplicate_stringโ signature:char*( const char *). Returns copy of a string. ๐list_createโ signature:void ( PList self, int size, int delta);. Creates a list instance with a staticListstructure. ๐plist_createโ signature:PList( int size, int delta);. Created list instance and returns newly allocatedListstructure. ๐list_destroyโ signature:void( PList self);. Destroys the list data. ๐งนplist_destroyโ signature:void ( PList self);. Destroys the list data and frees the list instance. ๐๏ธlist_addโ signature:int( PList self, Handle item);. Adds new item into a list, returns its index or -1 on error. โlist_insert_atโ signature:int ( PList self, Handle item, int pos);. Inserts new item into a list at a given position; returns its position or -1 on error. ๐list_atโ signature:Handle ( PList self, int index);. Returns the item that is located at a given index orNULL_HANDLEif the index is out of range. ๐ฏlist_deleteโ signature:void( PList self, Handle item);. Removes the item from the list. โlist_delete_atโ signature:void( PList self, int index);. Removes the item located at a given index from a list. โ๏ธlist_delete_allโ signature:void ( PList self, Bool kill);. Removes all items from the list. If thekillargument is true, callsfree()on every item before removing them from the list. ๐ฃlist_first_thatโ signature:int( PList self, void * action, void * params);. Enumerates all list entries, callingactionprocedure on each. If theactionreturns true, the enumeration stops and the index is returned. Otherwise, -1 is returned.actionhas to be a function declared as:
Bool action_callback( Handle item, void * params);
where params is a pointer to an arbitrary user data. ๐ง
list_index_ofโ signature:int( PList self, Handle item);. Returns index of an item, or -1 if the item is not in the list. ๐ข
โ๏ธ AUTHOR โ๏ธ
Dmitry Karasik, <dmitry@karasik.eu.org>. ๐
๐ SEE ALSO ๐
Prima. ๐
Okay that's the whole page, bestie! ๐ This manual page is from perl v5.42.0, dated 2024-08-20, and it's pod::Pr...nternals(3) โ mwah ๐
๐ฆ where this page comes from
- opensuse-leap 16.0: perl-Prima 1.74000-bp160.1.13 ยท AGPL-3.0-only AND BSD-2-Clause
- opensuse-leap 16.0: perl-Prima 1.74000-bp160.1.13 ยท AGPL-3.0-only AND BSD-2-Clause
- opensuse-leap 16.0: perl-Prima 1.74000-bp160.1.13 ยท AGPL-3.0-only AND BSD-2-Clause
- opensuse-leap 16.0: perl-Prima 1.74000-bp160.1.13 ยท AGPL-3.0-only AND BSD-2-Clause
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms