Skip to content

Instantly share code, notes, and snippets.

View pjlsergeant's full-sized avatar
🙇‍♂️
I don't really have time for this anymore

Peter Sergeant pjlsergeant

🙇‍♂️
I don't really have time for this anymore
  • Bangkok, Thailand
View GitHub Profile
@pjlsergeant
pjlsergeant / git.pl
Created November 27, 2012 12:42
GraphViz Git Commit Tree
#!perl
# Draw the commit graph of a git repository, using GraphViz. Supply the directory
# the repo is in as the first argument. Writes a file called 'repo.svg' to the CWD.
use strict; use warnings;
use Cwd;
use Git::PurePerl;
use GraphViz2;
@pjlsergeant
pjlsergeant / bubble.pl
Created November 27, 2012 09:23
BubbleCharts of DB Tables
#!perl
# Display a bubble chart of DB tables, with rows and relationships to other tables
# Either run directly: perl bubble.pl
# Or with Plack: plackup bubble.pl
use strict; use warnings;
# cpanm Dancer Template DBIx::Class::Schema::Loader Data::Google::Visualization::DataTable
use Dancer;
@pjlsergeant
pjlsergeant / gist:4125482
Created November 21, 2012 15:35
A mostly incorrect and misleading description of Perl's support of type classes...

Type classes elegantly allow the bringing together of both parametric and ad-hoc polymorphism. Functions with different implementations, different type signatures, but the same name can be both sensibly dispatched to depending on the data they're called on (ad-hoc polymorphism), and these functions can be composed and combined in ways agnostic to the underlying implementations, allowing the creation of functions that use the same implementation on different types (parametric polymorphism).

Type classes allow the definition of pseudo-data-types, defined by the named operations they support. Types can be expressed in terms of their capabilities, rather than in terms of their name - or as in object oriented programming, their ancestry.

While this is fantastically useful for statically typed languages, can type classes add utility to dynamically typed languages? Sadly the size of the set of all dynamically typed languages precludes a thorough examination in 1,000 words, leading to the choice to study how Perl h

@pjlsergeant
pjlsergeant / gist:4017266
Created November 5, 2012 13:48
List::SubFunctions
package List::SubFunctions;
sub smap (&@) {
my $sub = shift;
map {$sub->($_)} @_;
}
sub sgrep (&@) {
my $sub = shift;
grep {$sub->($_)} @_;
@pjlsergeant
pjlsergeant / gist:3992746
Created November 1, 2012 09:39
Two-line quicksort using part
sub qs {
my @i = part { 1 + ($_ <=> $_[0]) } @_;
return @i ? (qs(@{$i[0]}), @{$i[1]}, qs(@{$i[2]})) : ();
}
my $rs = bla->search({ foo => 'bar' });
die "Too many results" if $rs->count > 1;
return $rs->first;
---
my @r = bla->search({ foo => 'bar' });
die "Too many results" if @r > 1;
return $r[0];
@pjlsergeant
pjlsergeant / gist:3206885
Created July 30, 2012 13:24
Divide by three without using numeric operators...
use strict;
use warnings;
no warnings 'numeric';
print "$_ -> " . div3( $_ ) . "\n" for map { $_ / 10 } 0 .. 10;
print "$_ -> " . div3( $_ ) . "\n" for 0 .. 10;
sub div3 {
my $input = shift;
@pjlsergeant
pjlsergeant / gist:3081936
Created July 10, 2012 07:58
Idea for inline-testing and contracts for Perl method creation
method implication =>
applies => sub {
my ( $class, %args ) = @_;
return $args{'lhs'} <= $args{'rhs'};
},
to => {
lhs => { isa => 'Bool', required => 1 },
rhs => { isa => 'Bool', required => 1 },
},
yielding => 'Bool',
@pjlsergeant
pjlsergeant / selfgol.pl
Created July 9, 2012 13:36
Damien Conway's Selfgol
#!/usr/local/bin/perl -sw
$;=$/;seek+DATA,!++$/,!$s;$_=<DATA>;$s&&print||$g&&do{$y=($x||=20)*($y||8);sub
i{sleep&f}sub'p{print$;x$=,join$;,$b=~/.{$x}/g}$j=$j;sub'f{pop}sub
n{substr($b,&f%$y,3)=~tr,O,O,}sub'g{$f=&f-1;($w,$w,substr($b,&f,1),O)[n($f-$x)+
n($x+$f)-(substr($b,&f,1)eq+O)+n$f]||$w}$w="\40";$b=join'',@ARGV?<>:$_,$w
x$y;$b=~s).)$&=~/\w/?O:$w)ge;substr($b,$y)=q++;$g='$i=0;$i?$b:$c=$b;
substr+$c,$i,1,g$i;$g=~s?\d+?($&+1)%$y?e;$i-$y+1?eval$g:do{$i=-1;$b=$c;p;i
1}';sub'e{eval$g;&e}e}||eval||die+No.$;
__DATA__
if($j){{$^W=$|;*_=sub{$=+s=#([A-z])(.*)#=#$+$1#=g}}
@pjlsergeant
pjlsergeant / gist:3018266
Created June 29, 2012 14:27
Lazy constructors
package Acme::LazyConstruct;
use strict;
use warnings;
sub import {
my $pkg = caller(0);
$pkg = "main::$pkg" unless $pkg =~ m/::/;
eval "sub $pkg { $pkg->new }"; die $@ if $@;
}