pperl 0.6.23#

In development since 2026-10-11.

Modules#

  • MIME::Base64 uses vector instructions: on x86-64, encode_base64 and decode_base64 work 12 or 24 bytes at a time where the processor has SSSE3 or AVX2. A large text in lines of equal length is now also decoded on several threads, as large data already was encoded; a text laid out any other way, or with stray characters in it, decodes on one thread as before. The results are unchanged.

  • Digest::SHA uses the processor’s SHA instructions: the object interface (Digest::SHA->new, add, addfile) computes SHA-1 and SHA-256 with the processor’s SHA instructions where it has them, as the functions such as sha256_hex already did. SHA-1 and SHA-512 are faster without them too. On x86-64 processors without the SHA instructions, SHA-1, SHA-224 and SHA-256 are faster in every form - functions, objects and HMAC.

  • Encode converts single-byte encodings faster: encode and decode for iso-8859-x, the cp125x code pages, koi8 and the other single-byte encodings no longer search a table for every character, and a string perl holds as bytes is encoded without first being converted to UTF-8. A large encode or decode is also spread over several threads. The results, the check modes and the error messages are unchanged.

  • Cwd::getcwd is faster: getcwd and the lexer no longer clear buffers of up to 4 KiB that are written before they are read.

  • %Config entries that are not defined are undef: $Config{...} returned the string “undef”, which is true, for 232 keys such as d_faststdio and usedl, so if ($Config{d_faststdio}) took the branch for something the build does not have. They are undef now, as in perl; config_vars and config_sh still print them as 'undef'.

  • Compress::Raw::Zlib needs no system zlib: zlib is part of the binary now, as perl builds its own copy into the module, so IO::Compress, Archive::Tar and everything else on top of it work on a machine without libz and in the static build. Compression is 1.7 to 5.7 times as fast and decompression about twice as fast. A compressed stream is valid for every zlib but is not byte-for-byte the one perl writes, and ZLIB_VERSION reads 1.3.0-zlib-rs-0.6.8.

  • SDL_Quit with a Peta::WebGPU surface still alive no longer crashes: a program that called SDL_Quit while a surface or an unpresented frame was still in scope aborted with “double free or corruption” in about one run in ten. SDL_Quit now releases their swap chains first; using such a surface or frame afterwards dies with a message saying the window system was shut down, and the device keeps working.

  • Tie::Hash::Indexed is built in: the ordered hash of CPAN’s Tie::Hash::Indexed 0.08 loads without installing anything, as a tied hash and with its object interface, iterators and Storable support. Three sequences that crash perl with the original module work: pop, shift or clear in the middle of an each loop, and NEXTKEY before any FIRSTKEY.

  • PDL: broadcast_define and the dataflow inspectors: broadcast_define and thread_define now exist, with broadcastover and broadcastover_n under them. trans_parent and trans_children return PDL::Trans objects with their methods and vtable, so PDL::Core::pdump, pdump_trans and pdumphash work, as do flags and the *_nophys readers. Also new: add_threading_magic, remove_threading_magic, broadcast3, tocomplex, hdr_copy, hcpy and nslice_if_pdl.

  • PDL: an ndarray’s data is a Perl scalar: the scalar that get_dataref returns is now the data itself for every ndarray above 32 bytes, so writing into it writes the ndarray, as in PDL under perl. That makes new_around_datasv, new_around_pointer and set_data_by_file_map (an ndarray over a memory-mapped file) available. dump, bind and dowhenidle are new too, and datasv_refcount of an ndarray without such a scalar dies.

  • PDL: ldouble is the platform’s long double: ldouble and cldouble now hold the C compiler’s long double, the 80-bit format on x86-64, as PDL under perl does; they were a 128-bit type with different results. A single ldouble value no longer reads as 0 in print, sclr and conversions. The complex functions are exact: csqrt(-4) is 2i, not 1.22464679914735e-16+2i.

  • PDL: histograms, interpolate and the Image2D filters: new are histogram, whistogram, their 2-D forms and whist; wtstat, vcos, interpolate, diff2, diffcentred, partial, caverage and cavgover; and in PDL::Image2D conv2d, box2d, patch2d, patchbad2d, bilin2d, rescale2d and crop. hist without bounds now chooses its bins from the data as PDL under perl does. which no longer counts bad values, crossp and whichover broadcast and keep the type, and interpol fills an ndarray given as fourth argument.

  • PDL::ImageND: use PDL::ImageND loads, with convolveND, convolve, rebin, ninterpol, kernctr, circ_mean, circ_mean_p, contour_segments, contour_polylines, path_join, path_segs, combcoords, attract and repulse. PDL::FFT imports kernctr from it again, as PDL under perl does.

  • PDL: range and indexND as in PDL under perl: range accepts an index with fewer dimensions than the source and a size per dimension, honours every boundary condition (forbid, truncate, extend, periodic, mirror, one for all dimensions or one each), keeps the type, and its result is linked to the source, so a write into it reaches the source. rangeb is new. indexND gains the same.

  • PDL::Transform: use PDL::Transform loads: coordinate transformations as objects (t_linear, t_scale, t_offset, t_rot, t_lookup, t_fits, t_spherical, t_radial and the others), their composition and inversion, apply and invert, and map and unmap, which resample an image through a transformation. PDL::Transform::Cartography adds the map projections (t_mercator, t_orthographic, t_gnomonic and the others), graticule and clean_lines; earth_coast and earth_image need their data files from an installed PDL.

  • PDL: headers belong to the ndarray: an ndarray’s header (sethdr, gethdr, hdr) is released with the ndarray; it used to stay in memory, and a later ndarray could come up with a stranger’s header. With hdrcpy set, every operation now gives its result a deep copy of the header and the flag, where only slices did. sethdr refuses anything but a hash reference or undef.

  • PDL: accessors take their argument as PDL under perl does: nelem, dims, ndims, isnull, get_datatype, nbytes, sever, badflag and the like accept a number or an array reference as a one-off ndarray and die on the class name, where they returned 0 or nothing. After an explicit $pdl->DESTROY any use of $pdl dies with “Fatal error: ndarray address is NULL”. dimincs of a view gives the view’s increments, and readonly refuses a null ndarray.

  • PDL: a negative zero prints as -0 in a matrix: a matrix whose elements go through $PDL::doubleformat or $PDL::floatformat now formats each number itself, so -0 keeps its sign. $VERSION is 2.096 in PDL::Core and unset in PDL::Ufunc, PDL::Slices and the other generated modules, as in PDL; they all said 2.103.

  • PDL: set_debugging prints the trace: with PDL::Core::set_debugging(1) PDL prints what it does, step by step, to standard output, as PDL under perl does; it printed nothing.

  • PDL: badflag spreads as in PDL under perl: setting or clearing badflag now reaches the ndarrays it does in PDL: the parents of a view and their flowing children, not the other views of the same parent. Clearing it on a parent used to leave a view of a view set, and setting it never reached flowing children.

  • PDL 2.106: the embedded PDL is 2.106, up from 2.104. hclip and lclip work in place, PDL::Constants has DEG2RAD and RAD2DEG, and avgover, minover, maxover and the other “over” synonyms are methods only, no longer imported by use PDL. A condition on an ndarray of several elements dies with the full message of PDL, its PDL::overload_bool line included. The two functions new in 2.105, isnan and casinh, are not there yet.

  • Peta::Shell::Session evaluates Perl line by line: a new built-in module that runs pieces of Perl one after another and keeps what each leaves behind: my variables, pragmas, the current package. It says when a text is unfinished and returns the value of the last statement. It is the evaluator of ipps, the interactive mode.

Command line#

  • pperl -v describes the runtime in one line: the banner now says “It features JIT, auto-parallelization and GPU acceleration.”

  • –shell starts ipps, the interactive mode: pperl --shell, or pperl run under the name ipps, gives a prompt that runs Perl, prints the value of the last statement and keeps variables, subs and pragmas from line to line. It has line editing, history, a second prompt for unfinished input and a start file, ~/.pperl/ipps/rc.pl; without a terminal it reads lines from standard input. A bare pperl still reads a program from standard input as perl does. The reserved --interactive switch is gone.

  • ipps has commands, settings and macros: a line that starts with a colon and a word is a command: :help lists them. :vars shows the session’s variables, :time and :jit run a line and report on it, :dump shows a value whole, :source a sub’s code, :which where a module comes from; :install, :load, :save, :set, :history, :reset and :quit do what their names say. In ~/.pperl/ipps/rc.pl, Peta::Shell->macro, ->command and ->set define words that expand to Perl, commands of your own and settings.

  • ipps runs a command of your shell after !: a line that starts with ! and a space is handed to your shell and runs on the terminal, as in ! ls -l *.pl. It runs under $SHELL -c; the new shell setting changes that, for example to bash -ic for bash’s aliases. Without the space, ! is Perl’s negation as before.

  • ipps completes with Tab: the Tab key completes the word in front of the cursor: a variable of the session, a key of one of its hashes ($data->{list}[0]{ too), a method of an object or class, a sub, a module after use, a file name inside a string, a command, and a file name where none of those fits. A second Tab lists the candidates when there are several, and the prompt and the line are drawn again below the list; that holds for every program that completes through Term::ReadLine.

  • ipps shows a value as it is written in Perl: a number bare, a string in quotes, undef, true and false, an array or hash as its structure, an object with its class in front. A string gets the quotes that need the fewest escapes: '$5 each', q{it's}, "a\tb". Large values are cut with a note of what was left out, and the layout follows the width of the terminal. The value last shown is in $ans, and @ans when there were several.

  • –cpan runs the built-in CPAN client: pperl --cpan installs with the CPAN client that is part of the binary and no longer needs cpanm on the machine, so it works where no perl5 is installed. The options after --cpan are those of the cpan command, -T in place of --notest. A git repository, a directory or an archive file can still be named in place of a module.

  • –cpan installs only what loads after a failed XS build: when a distribution’s compile fails, --cpan installs its Perl files as before, but a module that loads the compiled part is now loaded once first and left out, by name, if it cannot load without it. A module that is only the front of its compiled part used to be installed and then reported as up to date on the next run. A directory named on the command line is covered too.

  • Built-in Perl modules count as installed: --cpan now also treats the Perl modules the binary carries, such as Test::More, as installed, at their versions. It used to read a host perl’s copies of them, or try to install them where there was none. Asked for a module that is built in, --cpan says so and builds nothing, also when CPAN has a newer release.

  • –native-manifest is gone: --cpan no longer writes pperl’s module inventory to disk, and the --native-manifest=DIR option that wrote it for other installers is removed. The installer asks Config::lib_file instead.

  • Modules for other operating systems are no longer built in: ExtUtils::MakeMaker’s and ExtUtils::CBuilder’s files for VMS, Windows, OS/2, AIX, macOS and other systems, 26 in all, and the vmsish pragma are no longer part of the binary. The File::Spec modules for other systems stay.

  • A host perl’s core directories are no longer searched: @INC no longer lists the core library directories of a perl5 installed on the machine, because every module in them is built into pperl and was never loaded from there. The site and vendor directories are searched as before, now under whichever perl version the host has.

  • Makefile.PL builds the Perl part only: ExtUtils::MakeMaker under pperl no longer tries to compile a distribution’s C or XS, so a Makefile.PL needs no compiler, no perl header files and no perl5 on the machine. A module that cannot load without its compiled part is left out and named, the rest of the distribution is built, and its own tests decide whether it is installed. The “different ideas about the architecture” notice is gone, and $Config{privlibexp} and $Config{archlibexp} name the built-in library.

  • Config::lib_files lists the built-in library: the new function Config::lib_files() returns the names of all library files inside the pperl binary, in the form require takes (File/Temp.pm).

  • Config::jit_counts says what the JIT has compiled: the new function Config::jit_counts() returns two numbers, the loops the JIT has compiled to machine code since the program started and the loops it has seen. It returns the empty list when the JIT is off.

  • Config::lib_file says where a library file is: the new function Config::lib_file("Foo/Bar.pm") returns the path under which pperl sees that file, a built-in one first, or undef. The path can be opened; a built-in module without Perl source reads as its package and version. ExtUtils::MakeMaker, Module::Metadata and CPAN ask it, so a Makefile.PL no longer reports a built-in prerequisite as not found.

Documentation#

  • A tutorial for ipps: a new tutorial, “ipps, the interactive mode”, walks through a first session, the commands, the start file with its settings and macros, and the places where a line at the prompt behaves differently from a line in a file.

  • Changelog translations: the changelog pages of versions 0.5.6 to 0.6.22 are translated into the 41 languages of the documentation. Entries of earlier versions name the Benchmarks Game programs and group the digits of large numbers the same way on every page, and two entries of 0.6.22 that were cut in two on the page read as one again.

  • Reference sidebar starts collapsed: the section navigation of the Reference shows one line per namespace when you enter it, and opens only the branch of the page you are reading. It used to open every namespace at once, which made the sidebar several hundred lines long.