SlideShare a Scribd company logo
1 of 56
Download to read offline
Lazyness, Impatienence, and Hubris:
Getting there on wheels we didn’t re-invent.
Steven Lembark
Workhorse Computing
lembark@wrkhors.com
True Lazyness is what ain’t.
Not banging your head against a wall.
Especially one that someone else has padded.
Don’t re-invent the wheel.
Don’t maintain someone else’s code.
Don’t correct your mistakes with 20/20 hindsight.
The utility of lazyness
“Utility” modules:
Simple
Lightweight
No configuration.
Avoid side effects.
The utility of impatience
Many use XS.
Faster, cleaner, simpler code.
Some examples:
Scalar::Util
List::Util
List::MoreUtils
File::Spec::Funcitons
IO::Util
List::Util & Scalar::Util
Graham Barr’s originals.
Where it all started.
The original idea behind Scalar::Util:
Scalar::Util contains a selection of subroutines
that people have expressed would be nice to have in
the perl core, but the usage would not really be
high enough to warrant the use of a keyword, and
the size would be so small that being individual
extensions would be wasteful.
Graham Barr
Scalar Util
use Scalar::Util
qw
(
blessed dualvar isdual readonly refaddr reftype
tainted weaken isweak isvstring looks_like_number
set_prototype
);
Builtin: ‘ref’
$a = ‘foo’;
$b = [ 1 .. 10 ];
$c = bless $b, ‘Foo::Bar’;
ref $a ’’
ref $b ’ARRAY’
ref $c ’Foo::Bar’
Builtin: ‘ref’
$a = ‘foo’;
$b = [ 1 .. 10 ];
$c = bless $b, ‘Foo::Bar’;
ref $a ’’
ref $b ’ARRAY’ Maybe not a class?
ref $c ’Foo::Bar’
blessed: class name
$a = ‘foo’;
$b = [ 1 .. 10 ];
$c = bless $b, ‘Foo::Bar’;
blessed $a ’’
blessed $b ’’
blessed $c ’Foo::Bar’
reftype: structure
$a = ‘foo’;
$b = [ 1 .. 10 ];
$c = bless $b, ‘Foo::Bar’;
reftype $a ’’
reftype $b ’ARRAY’
reftype $c ’ARRAY’
Using blessed
sub construct
{
my $proto = shift;
bless [], blessed $proto || $proto
}
If-logic for object vs. class name.
Using blessed
Sanity-check for an object
my $obj = shift;
blessed $obj
or croak 'Not a class method.';
using refaddr
Each object has a unique address.
say refaddr []; ’94141673084392’
say refaddr []; ’94141673084413’
using refaddr
Object-specific data by address:
sub inside_out_data
{
state $cache = {};
my $obj = shift;
my $data = $cache{ refaddr $obj } //= {};
...
}
using refaddr
Inside of inside-out objects:
sub inside_out_data
{
state $cache = {};
my $obj = shift;
my $data = $cache{ refaddr $obj } //= {};
...
}
Numeric Input
Perly regex for a number?
m{^ d+ $}x
6
Numeric Input
Perly regex for a number?
m{^ [-+]?d+ $}x
+6
Numeric Input
Perly regex for a number?
m{^ [-+]?d+(?:[.]d*)? $}x
+6.023
Numeric Input
Perly regex for a number?
m{^ [-+]?d+(?:[.]d*)?(?ed+)? $}x
+6.023e23
Numeric Input
Perly regex for a number?
m{^ [-+]?d+(?:[.]d*)?(?ed+)? $}x
+6.023e+23 +6.023e-23 0e0
0x1A 0b1110101 02347
Numeric Input
Whatever running perl thinks is numeric.
looks_like_number $x
Come full circle:
https://perldoc.perl.org/perl5360delta
#builtin-functions-(experimental)
A new core module builtin has been added,
which provides documentation for new always-
present functions that are built into the
interpreter.
Exposing yourself
Core functions exported by Scalar::Util.
use builtin
qw(
true false is_bool
weaken unweaken is_weak
blessed refaddr reftype
created_as_string created_as_number
ceil floor
trim
);
Exposing yourselfe
# exposed through Scalar::Utils::reftype
use builtin qw( ‘reftype' );
say "Reference type of arrays is ", reftype [];
Exposing yourself
# strip leading and trailing witespace:
# space, newline, tabs...
my $clean = trim $input;
Exposing yourself
# expand an array into offset + value pairs
while( my( $i, $val ) = indexed @array )
{
...
}
Exposing yourself
# boolean-only value
true false is_boolean
List::Util
Has grown over time
reduce reductions any all
none notall first max maxstr
min minstr product sum sum0
pairs unpairs pairkeys pairvalues
pairgrep pairfirst pairmap
shuffle sample uniq uniqint
uniqnum uniqstr head tail
zip mesh
List::Util
List reduction
reduce reductions any all
none notall first max maxstr
min minstr product sum sum0
pairs unpairs pairkeys pairvalues
pairgrep pairfirst pairmap
shuffle sample uniq uniqint
uniqnum uniqstr head tail
zip mesh
List::Util
Key/Value & Pairs
reduce reductions any all
none notall first max maxstr
min minstr product sum sum0
pairs unpairs pairkeys pairvalues
pairgrep pairfirst pairmap
shuffle sample uniq uniqint
uniqnum uniqstr head tail
zip mesh
List::Util
Misc list
reduce reductions any all
none notall first max maxstr
min minstr product sum sum0
pairs unpairs pairkeys pairvalues
pairgrep pairfirst pairmap
shuffle sample uniq uniqint
uniqnum uniqstr head tail
zip mesh
List::Util
Allows declarative code.
Fewer loops and side effects.
Nice for larger lists.
Reducing your workload.
Behaves like a for-loop, accumulating the final
value:
$result = { $a combine $b } @list;
my $sum = reduce { $a += $b } …
my $max = reduce { $a > $b ? $a : $b } …
my $min = reduce { $a < $b ? $a : $b }
Reducing your workload.
Make a dir with parents on *NIX:
qx{ mkdir -p $dir };
die “Oops: $!” if $?;
Reducing your workload.
use List::Util qw( reduce );
use File::Spec::Functions qw( catdir splitdir );
sub mkdir_p
{
my $dir = shift;
reduce
{
use autodie qw( mkdir );
$a = catdir $a, $b;
-d $a || mkdir $a;
$a
} ( ‘’, splitdir $dir )
}
Reducing your workload.
use List::Util qw( reduce );
use File::Spec::Functions qw( catdir splitdir );
sub mkdir_p
{
my $dir = shift;
reduce
{
use autodie qw( mkdir );
$a = catdir $a, $b;
-d $a || mkdir $a;
$a
} ( ‘’, splitdir $dir )
}
Reducing your workload.
use List::Util qw( reduce );
use File::Spec::Functions qw( catdir splitdir );
sub mkdir_p
{
my $dir = shift;
reduce
{
use autodie qw( mkdir );
$a = catdir $a, $b;
-d $a || mkdir $a;
$a
} ( ‘’, splitdir $dir )
}
Reducing your workload.
use List::Util qw( reduce );
use File::Spec::Functions qw( catdir splitdir );
sub mkdir_p
{
my $dir = shift;
reduce
{
use autodie qw( mkdir );
$a = catdir $a, $b;
-d $a || mkdir $a;
$a
} ( ‘’, splitdir $dir )
}
reductions returns all results
use List::Util qw( reductions );
use File::Spec::Functions qw( catdir splitdir );
sub mkdir_p
{
use autodie qw( mkdir );
-d || mkdir
for reductions { catdir $a, $b }
( ‘’, splitdir $_[0] )
}
Easy to combine
Lack of side-effects:
reduce + splitdir + catdir.
Easy to mix and match due.
Useful design principle.
Unique list in input order
Different than extracting hash keys.
Hash keys have random order.
uniq preserves input order.
Useful for exterally sorted data:
uniq map { … } @input_data;
Unique list in input order
Comparison types:
uniq
uniqint
uniqnum
uniqstr
Do the Perly Shuffle
Non-destructive selection without replacement:
my @random_order = shuffle @input;
my @random_subset = sample $count => @input;
Pair op’s derived from Raku
Pair = [ key => value ].
Raku hash == list of pairs.
pairgrep
Compares key & value from list.
unpairs
Flattens pairs into list.
Search keys & values in one pass
$a is a key, $b is a value.
Compare key or value without separating them.
my %subset
= pairgrep
{
$a # key
$b # value
}
%bighash;
Search keys & values in one pass
Reeeeellly nice for filtering hash values!
my %subset
= pairgrep
{
$b % 2
}
%bighash;
Heads I win...
Simple list operations:
head( N ) == first N elements
head( -N ) == all but last n elemens.
tail( N ) == last N items from list.
tail( -N ) == all but last N items.
Simple things done easily
Simple fix for an obvious step:
Build a hash from keys and values.
my %hash = zip @keyz, @valz;
But wait! There’s more!!!
Junctions
Treatment of an empty list
all BLOCK LIST
all_u BLOCK LIST
any BLOCK LIST
any_u BLOCK LIST
none BLOCK LIST
none_u BLOCK LIST
notall BLOCK LIST
notall_u BLOCK LIST
one BLOCK LIST
one_u BLOCK LIST
Transformation
apply BLOCK LIST
insert_after BLOCK VALUE LIST
insert_after_string STRING VALUE LIST
pairwise BLOCK ARRAY1 ARRAY2
mesh ARRAY1 ARRAY2 [ ARRAY3 ... ]
zip ARRAY1 ARRAY2 [ ARRAY3 ... ]
zip6
zip_unflatten
listcmp ARRAY0 ARRAY1 [ ARRAY2 ... ]
arrayify LIST[,LIST[,LIST...]]
uniq LIST
distinct LIST
singleton LIST
duplicates LIST
frequency LIST
occurrences LIST
mode LIST
slide BLOCK LIST
Partitioning
after BLOCK LIST
after_incl BLOCK LIST
before BLOCK LIST
before_incl BLOCK LIST
part BLOCK LIST
samples COUNT LIST
Iteration
each_array ARRAY1 ARRAY2 ...
each_arrayref LIST
natatime EXPR, LIST
slideatatime STEP, WINDOW, LIST
Searching
firstval BLOCK LIST
first_value BLOCK LIST
onlyval BLOCK LIST
only_value BLOCK LIST
lastval BLOCK LIST
last_value BLOCK LIST
firstres BLOCK LIST
first_result BLOCK LIST
onlyres BLOCK LIST
only_result BLOCK LIST
lastres BLOCK LIST
last_result BLOCK LIST
indexes BLOCK LIST
firstidx BLOCK LIST
first_index BLOCK LIST
onlyidx BLOCK LIST
only_index BLOCK LIST
lastidx BLOCK LIST
last_index BLOCK LIST
Sorting
sort_by BLOCK LIST
nsort_by BLOCK LIST
qsort BLOCK ARRAY
Searching in sorted Lists
bsearch BLOCK LIST
bsearchidx BLOCK LIST
bsearch_index BLOCK LIST
lower_bound BLOCK LIST
upper_bound BLOCK LIST
equal_range BLOCK LIST
Operations on sorted Lists
binsert BLOCK ITEM LIST
bsearch_insert BLOCK ITEM LIST
bremove BLOCK LIST
bsearch_remove BLOCK LIST
Counting and calculation
true BLOCK LIST
false BLOCK LIST
reduce_0 BLOCK LIST
reduce_1 BLOCK LIST
reduce_u BLOCK LIST
minmax LIST
minmaxstr LIST
List::MoreUtils
Junctions
Treatment of an empty list
all BLOCK LIST
all_u BLOCK LIST
any BLOCK LIST
any_u BLOCK LIST
none BLOCK LIST
none_u BLOCK LIST
notall BLOCK LIST
notall_u BLOCK LIST
one BLOCK LIST
one_u BLOCK LIST
Transformation
apply BLOCK LIST
insert_after BLOCK VALUE LIST
insert_after_string STRING VALUE LIST
pairwise BLOCK ARRAY1 ARRAY2
mesh ARRAY1 ARRAY2 [ ARRAY3 ... ]
zip ARRAY1 ARRAY2 [ ARRAY3 ... ]
zip6
zip_unflatten
listcmp ARRAY0 ARRAY1 [ ARRAY2 ... ]
arrayify LIST[,LIST[,LIST...]]
uniq LIST
distinct LIST
singleton LIST
duplicates LIST
frequency LIST
occurrences LIST
mode LIST
slide BLOCK LIST
Partitioning
after BLOCK LIST
after_incl BLOCK LIST
before BLOCK LIST
before_incl BLOCK LIST
part BLOCK LIST
samples COUNT LIST
Iteration
each_array ARRAY1 ARRAY2 ...
each_arrayref LIST
natatime EXPR, LIST
slideatatime STEP, WINDOW, LIST
Searching
firstval BLOCK LIST
first_value BLOCK LIST
onlyval BLOCK LIST
only_value BLOCK LIST
lastval BLOCK LIST
last_value BLOCK LIST
firstres BLOCK LIST
first_result BLOCK LIST
onlyres BLOCK LIST
only_result BLOCK LIST
lastres BLOCK LIST
last_result BLOCK LIST
indexes BLOCK LIST
firstidx BLOCK LIST
first_index BLOCK LIST
onlyidx BLOCK LIST
only_index BLOCK LIST
lastidx BLOCK LIST
last_index BLOCK LIST
Sorting
sort_by BLOCK LIST
nsort_by BLOCK LIST
qsort BLOCK ARRAY
Searching in sorted Lists
bsearch BLOCK LIST
bsearchidx BLOCK LIST
bsearch_index BLOCK LIST
lower_bound BLOCK LIST
upper_bound BLOCK LIST
equal_range BLOCK LIST
Operations on sorted Lists
binsert BLOCK ITEM LIST
bsearch_insert BLOCK ITEM LIST
bremove BLOCK LIST
bsearch_remove BLOCK LIST
Counting and calculation
true BLOCK LIST
false BLOCK LIST
reduce_0 BLOCK LIST
reduce_1 BLOCK LIST
reduce_u BLOCK LIST
minmax LIST
minmaxstr LIST
IO::Util
Capture stdout or stderr in a scalar:
my $output_ref = capture { ... print ... };
IO::Util
Capture stdout or stderr in a scalar:
my $output_ref
= capture
{
print ‘this’;
...
print ‘that’;
};
IO::Util
Capture stdout or stderr in a scalar:
my $output_ref
= capture
{
say “Output from ‘$exec’”, qx{ $exec };
};
Hundreds more...
“::Util” on metacpan.
Hundreds of modules.
Lots of ways not to re-invent the wheel.

More Related Content

Similar to Wheels we didn't re-invent: Perl's Utility Modules

PerlApp2Postgresql (2)
PerlApp2Postgresql (2)PerlApp2Postgresql (2)
PerlApp2Postgresql (2)Jerome Eteve
 
DBIx::Class introduction - 2010
DBIx::Class introduction - 2010DBIx::Class introduction - 2010
DBIx::Class introduction - 2010leo lapworth
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)Night Sailer
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginnersleo lapworth
 
How to write code you won't hate tomorrow
How to write code you won't hate tomorrowHow to write code you won't hate tomorrow
How to write code you won't hate tomorrowPete McFarlane
 
Functional Javascript
Functional JavascriptFunctional Javascript
Functional Javascriptguest4d57e6
 
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探台灣資料科學年會
 
Functional Algebra: Monoids Applied
Functional Algebra: Monoids AppliedFunctional Algebra: Monoids Applied
Functional Algebra: Monoids AppliedSusan Potter
 
hello- please dont just copy from other answers- the following is the.docx
hello- please dont just copy from other answers- the following is the.docxhello- please dont just copy from other answers- the following is the.docx
hello- please dont just copy from other answers- the following is the.docxIsaac9LjWelchq
 
Making an Object System with Tcl 8.5
Making an Object System with Tcl 8.5Making an Object System with Tcl 8.5
Making an Object System with Tcl 8.5Donal Fellows
 
Tips for using Firebird system tables
Tips for using Firebird system tablesTips for using Firebird system tables
Tips for using Firebird system tablesMind The Firebird
 
Functional perl
Functional perlFunctional perl
Functional perlErrorific
 
maincpp Build and procees a sorted linked list of Patie.pdf
maincpp   Build and procees a sorted linked list of Patie.pdfmaincpp   Build and procees a sorted linked list of Patie.pdf
maincpp Build and procees a sorted linked list of Patie.pdfadityastores21
 
Everything About PowerShell
Everything About PowerShellEverything About PowerShell
Everything About PowerShellGaetano Causio
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Jeff Carouth
 
Please solve the following problem using C++- Thank you Instructions-.docx
Please solve the following problem using C++- Thank you Instructions-.docxPlease solve the following problem using C++- Thank you Instructions-.docx
Please solve the following problem using C++- Thank you Instructions-.docxPeterlqELawrenceb
 
PHP record- with all programs and output
PHP record- with all programs and outputPHP record- with all programs and output
PHP record- with all programs and outputKavithaK23
 

Similar to Wheels we didn't re-invent: Perl's Utility Modules (20)

PerlApp2Postgresql (2)
PerlApp2Postgresql (2)PerlApp2Postgresql (2)
PerlApp2Postgresql (2)
 
DBIx::Class introduction - 2010
DBIx::Class introduction - 2010DBIx::Class introduction - 2010
DBIx::Class introduction - 2010
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginners
 
How to write code you won't hate tomorrow
How to write code you won't hate tomorrowHow to write code you won't hate tomorrow
How to write code you won't hate tomorrow
 
Functional Javascript
Functional JavascriptFunctional Javascript
Functional Javascript
 
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
[DSC 2016] 系列活動:李泳泉 / 星火燎原 - Spark 機器學習初探
 
Functional Algebra: Monoids Applied
Functional Algebra: Monoids AppliedFunctional Algebra: Monoids Applied
Functional Algebra: Monoids Applied
 
hello- please dont just copy from other answers- the following is the.docx
hello- please dont just copy from other answers- the following is the.docxhello- please dont just copy from other answers- the following is the.docx
hello- please dont just copy from other answers- the following is the.docx
 
Making an Object System with Tcl 8.5
Making an Object System with Tcl 8.5Making an Object System with Tcl 8.5
Making an Object System with Tcl 8.5
 
Perl
PerlPerl
Perl
 
Tips for using Firebird system tables
Tips for using Firebird system tablesTips for using Firebird system tables
Tips for using Firebird system tables
 
SPL, not a bridge too far
SPL, not a bridge too farSPL, not a bridge too far
SPL, not a bridge too far
 
Functional perl
Functional perlFunctional perl
Functional perl
 
maincpp Build and procees a sorted linked list of Patie.pdf
maincpp   Build and procees a sorted linked list of Patie.pdfmaincpp   Build and procees a sorted linked list of Patie.pdf
maincpp Build and procees a sorted linked list of Patie.pdf
 
Everything About PowerShell
Everything About PowerShellEverything About PowerShell
Everything About PowerShell
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
Please solve the following problem using C++- Thank you Instructions-.docx
Please solve the following problem using C++- Thank you Instructions-.docxPlease solve the following problem using C++- Thank you Instructions-.docx
Please solve the following problem using C++- Thank you Instructions-.docx
 
PHP record- with all programs and output
PHP record- with all programs and outputPHP record- with all programs and output
PHP record- with all programs and output
 

More from Workhorse Computing

Paranormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpParanormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpWorkhorse Computing
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.Workhorse Computing
 
Generating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlGenerating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlWorkhorse Computing
 
Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Workhorse Computing
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationWorkhorse Computing
 
BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationWorkhorse Computing
 
The W-curve and its application.
The W-curve and its application.The W-curve and its application.
The W-curve and its application.Workhorse Computing
 
Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Workhorse Computing
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Workhorse Computing
 

More from Workhorse Computing (20)

mro-every.pdf
mro-every.pdfmro-every.pdf
mro-every.pdf
 
Paranormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpParanormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add Up
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.
 
Unit Testing Lots of Perl
Unit Testing Lots of PerlUnit Testing Lots of Perl
Unit Testing Lots of Perl
 
Generating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlGenerating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in Posgresql
 
Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!Hypers and Gathers and Takes! Oh my!
Hypers and Gathers and Takes! Oh my!
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command Interpolation
 
Findbin libs
Findbin libsFindbin libs
Findbin libs
 
Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
 
BASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic InterpolationBASH Variables Part 1: Basic Interpolation
BASH Variables Part 1: Basic Interpolation
 
Effective Benchmarks
Effective BenchmarksEffective Benchmarks
Effective Benchmarks
 
Metadata-driven Testing
Metadata-driven TestingMetadata-driven Testing
Metadata-driven Testing
 
The W-curve and its application.
The W-curve and its application.The W-curve and its application.
The W-curve and its application.
 
Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.Keeping objects healthy with Object::Exercise.
Keeping objects healthy with Object::Exercise.
 
Smoking docker
Smoking dockerSmoking docker
Smoking docker
 
Getting Testy With Perl6
Getting Testy With Perl6Getting Testy With Perl6
Getting Testy With Perl6
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
 
Neatly folding-a-tree
Neatly folding-a-treeNeatly folding-a-tree
Neatly folding-a-tree
 
Light my-fuse
Light my-fuseLight my-fuse
Light my-fuse
 
Paranormal stats
Paranormal statsParanormal stats
Paranormal stats
 

Recently uploaded

Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetEnjoy Anytime
 
Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Hyundai Motor Group
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 

Recently uploaded (20)

Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
 
Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2Next-generation AAM aircraft unveiled by Supernal, S-A2
Next-generation AAM aircraft unveiled by Supernal, S-A2
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 

Wheels we didn't re-invent: Perl's Utility Modules

  • 1. Lazyness, Impatienence, and Hubris: Getting there on wheels we didn’t re-invent. Steven Lembark Workhorse Computing lembark@wrkhors.com
  • 2. True Lazyness is what ain’t. Not banging your head against a wall. Especially one that someone else has padded. Don’t re-invent the wheel. Don’t maintain someone else’s code. Don’t correct your mistakes with 20/20 hindsight.
  • 3. The utility of lazyness “Utility” modules: Simple Lightweight No configuration. Avoid side effects.
  • 4. The utility of impatience Many use XS. Faster, cleaner, simpler code.
  • 6. List::Util & Scalar::Util Graham Barr’s originals. Where it all started.
  • 7. The original idea behind Scalar::Util: Scalar::Util contains a selection of subroutines that people have expressed would be nice to have in the perl core, but the usage would not really be high enough to warrant the use of a keyword, and the size would be so small that being individual extensions would be wasteful. Graham Barr
  • 8. Scalar Util use Scalar::Util qw ( blessed dualvar isdual readonly refaddr reftype tainted weaken isweak isvstring looks_like_number set_prototype );
  • 9. Builtin: ‘ref’ $a = ‘foo’; $b = [ 1 .. 10 ]; $c = bless $b, ‘Foo::Bar’; ref $a ’’ ref $b ’ARRAY’ ref $c ’Foo::Bar’
  • 10. Builtin: ‘ref’ $a = ‘foo’; $b = [ 1 .. 10 ]; $c = bless $b, ‘Foo::Bar’; ref $a ’’ ref $b ’ARRAY’ Maybe not a class? ref $c ’Foo::Bar’
  • 11. blessed: class name $a = ‘foo’; $b = [ 1 .. 10 ]; $c = bless $b, ‘Foo::Bar’; blessed $a ’’ blessed $b ’’ blessed $c ’Foo::Bar’
  • 12. reftype: structure $a = ‘foo’; $b = [ 1 .. 10 ]; $c = bless $b, ‘Foo::Bar’; reftype $a ’’ reftype $b ’ARRAY’ reftype $c ’ARRAY’
  • 13. Using blessed sub construct { my $proto = shift; bless [], blessed $proto || $proto } If-logic for object vs. class name.
  • 14. Using blessed Sanity-check for an object my $obj = shift; blessed $obj or croak 'Not a class method.';
  • 15. using refaddr Each object has a unique address. say refaddr []; ’94141673084392’ say refaddr []; ’94141673084413’
  • 16. using refaddr Object-specific data by address: sub inside_out_data { state $cache = {}; my $obj = shift; my $data = $cache{ refaddr $obj } //= {}; ... }
  • 17. using refaddr Inside of inside-out objects: sub inside_out_data { state $cache = {}; my $obj = shift; my $data = $cache{ refaddr $obj } //= {}; ... }
  • 18. Numeric Input Perly regex for a number? m{^ d+ $}x 6
  • 19. Numeric Input Perly regex for a number? m{^ [-+]?d+ $}x +6
  • 20. Numeric Input Perly regex for a number? m{^ [-+]?d+(?:[.]d*)? $}x +6.023
  • 21. Numeric Input Perly regex for a number? m{^ [-+]?d+(?:[.]d*)?(?ed+)? $}x +6.023e23
  • 22. Numeric Input Perly regex for a number? m{^ [-+]?d+(?:[.]d*)?(?ed+)? $}x +6.023e+23 +6.023e-23 0e0 0x1A 0b1110101 02347
  • 23. Numeric Input Whatever running perl thinks is numeric. looks_like_number $x
  • 24. Come full circle: https://perldoc.perl.org/perl5360delta #builtin-functions-(experimental) A new core module builtin has been added, which provides documentation for new always- present functions that are built into the interpreter.
  • 25. Exposing yourself Core functions exported by Scalar::Util. use builtin qw( true false is_bool weaken unweaken is_weak blessed refaddr reftype created_as_string created_as_number ceil floor trim );
  • 26. Exposing yourselfe # exposed through Scalar::Utils::reftype use builtin qw( ‘reftype' ); say "Reference type of arrays is ", reftype [];
  • 27. Exposing yourself # strip leading and trailing witespace: # space, newline, tabs... my $clean = trim $input;
  • 28. Exposing yourself # expand an array into offset + value pairs while( my( $i, $val ) = indexed @array ) { ... }
  • 29. Exposing yourself # boolean-only value true false is_boolean
  • 30. List::Util Has grown over time reduce reductions any all none notall first max maxstr min minstr product sum sum0 pairs unpairs pairkeys pairvalues pairgrep pairfirst pairmap shuffle sample uniq uniqint uniqnum uniqstr head tail zip mesh
  • 31. List::Util List reduction reduce reductions any all none notall first max maxstr min minstr product sum sum0 pairs unpairs pairkeys pairvalues pairgrep pairfirst pairmap shuffle sample uniq uniqint uniqnum uniqstr head tail zip mesh
  • 32. List::Util Key/Value & Pairs reduce reductions any all none notall first max maxstr min minstr product sum sum0 pairs unpairs pairkeys pairvalues pairgrep pairfirst pairmap shuffle sample uniq uniqint uniqnum uniqstr head tail zip mesh
  • 33. List::Util Misc list reduce reductions any all none notall first max maxstr min minstr product sum sum0 pairs unpairs pairkeys pairvalues pairgrep pairfirst pairmap shuffle sample uniq uniqint uniqnum uniqstr head tail zip mesh
  • 34. List::Util Allows declarative code. Fewer loops and side effects. Nice for larger lists.
  • 35. Reducing your workload. Behaves like a for-loop, accumulating the final value: $result = { $a combine $b } @list; my $sum = reduce { $a += $b } … my $max = reduce { $a > $b ? $a : $b } … my $min = reduce { $a < $b ? $a : $b }
  • 36. Reducing your workload. Make a dir with parents on *NIX: qx{ mkdir -p $dir }; die “Oops: $!” if $?;
  • 37. Reducing your workload. use List::Util qw( reduce ); use File::Spec::Functions qw( catdir splitdir ); sub mkdir_p { my $dir = shift; reduce { use autodie qw( mkdir ); $a = catdir $a, $b; -d $a || mkdir $a; $a } ( ‘’, splitdir $dir ) }
  • 38. Reducing your workload. use List::Util qw( reduce ); use File::Spec::Functions qw( catdir splitdir ); sub mkdir_p { my $dir = shift; reduce { use autodie qw( mkdir ); $a = catdir $a, $b; -d $a || mkdir $a; $a } ( ‘’, splitdir $dir ) }
  • 39. Reducing your workload. use List::Util qw( reduce ); use File::Spec::Functions qw( catdir splitdir ); sub mkdir_p { my $dir = shift; reduce { use autodie qw( mkdir ); $a = catdir $a, $b; -d $a || mkdir $a; $a } ( ‘’, splitdir $dir ) }
  • 40. Reducing your workload. use List::Util qw( reduce ); use File::Spec::Functions qw( catdir splitdir ); sub mkdir_p { my $dir = shift; reduce { use autodie qw( mkdir ); $a = catdir $a, $b; -d $a || mkdir $a; $a } ( ‘’, splitdir $dir ) }
  • 41. reductions returns all results use List::Util qw( reductions ); use File::Spec::Functions qw( catdir splitdir ); sub mkdir_p { use autodie qw( mkdir ); -d || mkdir for reductions { catdir $a, $b } ( ‘’, splitdir $_[0] ) }
  • 42. Easy to combine Lack of side-effects: reduce + splitdir + catdir. Easy to mix and match due. Useful design principle.
  • 43. Unique list in input order Different than extracting hash keys. Hash keys have random order. uniq preserves input order. Useful for exterally sorted data: uniq map { … } @input_data;
  • 44. Unique list in input order Comparison types: uniq uniqint uniqnum uniqstr
  • 45. Do the Perly Shuffle Non-destructive selection without replacement: my @random_order = shuffle @input; my @random_subset = sample $count => @input;
  • 46. Pair op’s derived from Raku Pair = [ key => value ]. Raku hash == list of pairs. pairgrep Compares key & value from list. unpairs Flattens pairs into list.
  • 47. Search keys & values in one pass $a is a key, $b is a value. Compare key or value without separating them. my %subset = pairgrep { $a # key $b # value } %bighash;
  • 48. Search keys & values in one pass Reeeeellly nice for filtering hash values! my %subset = pairgrep { $b % 2 } %bighash;
  • 49. Heads I win... Simple list operations: head( N ) == first N elements head( -N ) == all but last n elemens. tail( N ) == last N items from list. tail( -N ) == all but last N items.
  • 50. Simple things done easily Simple fix for an obvious step: Build a hash from keys and values. my %hash = zip @keyz, @valz;
  • 51. But wait! There’s more!!! Junctions Treatment of an empty list all BLOCK LIST all_u BLOCK LIST any BLOCK LIST any_u BLOCK LIST none BLOCK LIST none_u BLOCK LIST notall BLOCK LIST notall_u BLOCK LIST one BLOCK LIST one_u BLOCK LIST Transformation apply BLOCK LIST insert_after BLOCK VALUE LIST insert_after_string STRING VALUE LIST pairwise BLOCK ARRAY1 ARRAY2 mesh ARRAY1 ARRAY2 [ ARRAY3 ... ] zip ARRAY1 ARRAY2 [ ARRAY3 ... ] zip6 zip_unflatten listcmp ARRAY0 ARRAY1 [ ARRAY2 ... ] arrayify LIST[,LIST[,LIST...]] uniq LIST distinct LIST singleton LIST duplicates LIST frequency LIST occurrences LIST mode LIST slide BLOCK LIST Partitioning after BLOCK LIST after_incl BLOCK LIST before BLOCK LIST before_incl BLOCK LIST part BLOCK LIST samples COUNT LIST Iteration each_array ARRAY1 ARRAY2 ... each_arrayref LIST natatime EXPR, LIST slideatatime STEP, WINDOW, LIST Searching firstval BLOCK LIST first_value BLOCK LIST onlyval BLOCK LIST only_value BLOCK LIST lastval BLOCK LIST last_value BLOCK LIST firstres BLOCK LIST first_result BLOCK LIST onlyres BLOCK LIST only_result BLOCK LIST lastres BLOCK LIST last_result BLOCK LIST indexes BLOCK LIST firstidx BLOCK LIST first_index BLOCK LIST onlyidx BLOCK LIST only_index BLOCK LIST lastidx BLOCK LIST last_index BLOCK LIST Sorting sort_by BLOCK LIST nsort_by BLOCK LIST qsort BLOCK ARRAY Searching in sorted Lists bsearch BLOCK LIST bsearchidx BLOCK LIST bsearch_index BLOCK LIST lower_bound BLOCK LIST upper_bound BLOCK LIST equal_range BLOCK LIST Operations on sorted Lists binsert BLOCK ITEM LIST bsearch_insert BLOCK ITEM LIST bremove BLOCK LIST bsearch_remove BLOCK LIST Counting and calculation true BLOCK LIST false BLOCK LIST reduce_0 BLOCK LIST reduce_1 BLOCK LIST reduce_u BLOCK LIST minmax LIST minmaxstr LIST
  • 52. List::MoreUtils Junctions Treatment of an empty list all BLOCK LIST all_u BLOCK LIST any BLOCK LIST any_u BLOCK LIST none BLOCK LIST none_u BLOCK LIST notall BLOCK LIST notall_u BLOCK LIST one BLOCK LIST one_u BLOCK LIST Transformation apply BLOCK LIST insert_after BLOCK VALUE LIST insert_after_string STRING VALUE LIST pairwise BLOCK ARRAY1 ARRAY2 mesh ARRAY1 ARRAY2 [ ARRAY3 ... ] zip ARRAY1 ARRAY2 [ ARRAY3 ... ] zip6 zip_unflatten listcmp ARRAY0 ARRAY1 [ ARRAY2 ... ] arrayify LIST[,LIST[,LIST...]] uniq LIST distinct LIST singleton LIST duplicates LIST frequency LIST occurrences LIST mode LIST slide BLOCK LIST Partitioning after BLOCK LIST after_incl BLOCK LIST before BLOCK LIST before_incl BLOCK LIST part BLOCK LIST samples COUNT LIST Iteration each_array ARRAY1 ARRAY2 ... each_arrayref LIST natatime EXPR, LIST slideatatime STEP, WINDOW, LIST Searching firstval BLOCK LIST first_value BLOCK LIST onlyval BLOCK LIST only_value BLOCK LIST lastval BLOCK LIST last_value BLOCK LIST firstres BLOCK LIST first_result BLOCK LIST onlyres BLOCK LIST only_result BLOCK LIST lastres BLOCK LIST last_result BLOCK LIST indexes BLOCK LIST firstidx BLOCK LIST first_index BLOCK LIST onlyidx BLOCK LIST only_index BLOCK LIST lastidx BLOCK LIST last_index BLOCK LIST Sorting sort_by BLOCK LIST nsort_by BLOCK LIST qsort BLOCK ARRAY Searching in sorted Lists bsearch BLOCK LIST bsearchidx BLOCK LIST bsearch_index BLOCK LIST lower_bound BLOCK LIST upper_bound BLOCK LIST equal_range BLOCK LIST Operations on sorted Lists binsert BLOCK ITEM LIST bsearch_insert BLOCK ITEM LIST bremove BLOCK LIST bsearch_remove BLOCK LIST Counting and calculation true BLOCK LIST false BLOCK LIST reduce_0 BLOCK LIST reduce_1 BLOCK LIST reduce_u BLOCK LIST minmax LIST minmaxstr LIST
  • 53. IO::Util Capture stdout or stderr in a scalar: my $output_ref = capture { ... print ... };
  • 54. IO::Util Capture stdout or stderr in a scalar: my $output_ref = capture { print ‘this’; ... print ‘that’; };
  • 55. IO::Util Capture stdout or stderr in a scalar: my $output_ref = capture { say “Output from ‘$exec’”, qx{ $exec }; };
  • 56. Hundreds more... “::Util” on metacpan. Hundreds of modules. Lots of ways not to re-invent the wheel.