Alien-libssh

 view release on metacpan or  search on metacpan

.claude/skills/getty-perl-core/SKILL.md  view on Meta::CPAN


## Errors

- **`croak`, never `die`.** Errors report the caller's line, not ours.
- **Import it:** `use Carp qw( croak );` and call `croak(...)` bare.
- **Name the origin in the message:** `croak __PACKAGE__."->state too many args"` — or whatever identifies the operation in that module's DSL.

## Strings

- **Concatenate, do not interpolate:** `'Adding '.$f.' with '.$length.' bytes'`. Interpolate only where concatenation would be unreadable.
- **Single quotes by default.** `'...'` and `"..."` are genuinely different in Perl — `"` interpolates and processes escapes, `'` does not. Reach for `"` when you need that, not by habit.
- **Import lists as `qw( croak confess )`** — spaces inside the parens. Never rely on default exports.

## Control flow

- **Postfix `if`/`unless`** for guards and short conditions: `croak(...) if $self->readonly;`
- **`unless $x`** instead of `if !$x`.
- **Guard clauses return bare:** `return unless $res->is_success;` — not `return undef;`.
- **Nested ternaries** for a return that picks between expressions, instead of an if/elsif chain.

## Data

.claude/skills/perl-xs/SKILL.md  view on Meta::CPAN


The vtable address is also the type check. `mg_findext(sv, PERL_MAGIC_ext,
&Foo_magic)` matches only magic carrying that exact vtable, so a hand-blessed
hashref croaks at the boundary instead of segfaulting through an `INT2PTR` cast on
a pointer that was never there. That is the reason to skip `T_PTROBJ`, which stores
the pointer with `sv_setref_pv` and offers neither a free hook nor a real type
check.

## Four ways it goes wrong

1. **An unescaped `"` in the typemap.** xsubpp reads INPUT/OUTPUT templates as Perl
   double-quoted strings, so a quote meant for the generated C must be written
   `\"`. The failure surfaces as a C syntax error in code you never wrote.
2. **The refcount taken on the wrong SV.** `ST(0)` is the reference; `SvRV(ST(0))`
   is the blessed referent carrying the magic. A child object that keeps its parent
   alive must increment the **referent** — incrementing `ST(0)` survives scope exit
   and segfaults on `undef $parent`, which is the case tests reach for last.
3. **`XSRETURN_UNDEF` bypasses the OUTPUT section.** It is the way to return undef
   instead of an object, and it means everything allocated up to that point leaks
   unless the branch frees it first.
4. **A NULL handle the C library tolerates.** After a close or free, many libraries

.claude/skills/perl-xs/references/typemap.md  view on Meta::CPAN

|---|---|
| `$var` | the C variable being filled (INPUT) or read (OUTPUT) |
| `$arg` | the SV on the argument stack — `ST(n)` |
| `$type` | the C type, with `*` mangled to `Ptr` |
| `${pname}` | the fully qualified Perl name of the XSUB, for error messages |
| `$ntype` | the type without the `Ptr` suffix |

## The escaping rule

xsubpp evaluates INPUT/OUTPUT templates as **Perl double-quoted strings**. Every `"`
that has to reach the generated C must be written `\"`; an unescaped one ends the
Perl string early and the failure surfaces as an unrelated C syntax error, often
pointing at a line that looks fine.

```
# Wrong:    sv_magicext(newSVrv($arg, "Foo"), ...);
# Correct:  sv_magicext(newSVrv($arg, \"Foo\"), ...);
```

The same holds for `$` and `@` that are meant literally in the C code — escape them.

## The pattern for an object type

INPUT finds the magic and croaks if it is not there; OUTPUT creates the blessed SV
and attaches the magic. Together they mean an XSUB body only ever assigns `RETVAL`
— **blessing is the typemap's job, never the XSUB's.**

```
INPUT
T_FOO



( run in 3.368 seconds using v1.01-cache-2.11-cpan-54e63673c56 )