Compare commits
8 Commits
becd0095d8
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 9bf4ffad38 | |||
| e6befea75e | |||
| 3a781a129a | |||
| 2769994edd | |||
| 4fe312929b | |||
| 4de7c25d59 | |||
| 3382f6d33f | |||
| ac2ad23230 |
BIN
assets/no_bad_hair_days.png
Normal file
BIN
assets/no_bad_hair_days.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 736 B |
BIN
assets/powered_by_netbsd.png
Normal file
BIN
assets/powered_by_netbsd.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
173
index.html
173
index.html
@@ -1,84 +1,95 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>rawley.xyz</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="description" value="Rawley Fowler's personal website, about Perl, Emacs and Software in General.">
|
||||
<link rel="stylesheet" href="index.css">
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<p>
|
||||
Hi, I'm Rawley. I'm a full-time Husband, Dad, Emacs evangelist and Perl aficionado.
|
||||
</p>
|
||||
<p>
|
||||
I am the creator of many <a href="https://www.gnu.org/philosophy/free-sw.en.html">free-software</a> libraries and tools.
|
||||
I have extensive knowledge of Perl, Java, JVM, and Functional Programming. I'm always working on something, whether it be my
|
||||
100 year old house, or some 100 year old code.
|
||||
</p>
|
||||
<p>
|
||||
I'm always looking for interesting things to work on.
|
||||
If you have a project you think might suite me, send me an email at <strong>rawley</strong> at <strong>molluscsoftware.com</strong>
|
||||
</p>
|
||||
<h2>Blog Posts</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/posts/perl-in-2025.html">Perl in 2025</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/niche-software.html">Using a niche programming language</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/dancer2-controllers.html">Dancer2::Controllers and Perl Attributes</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/perl-oo-action-benchmark.html">Perl OO benchmarks</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/maybe-escaping-evil.html">Exploring <code>evil-mode</code> alternatives</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/in-defense-of-global-variables.html">How to Properly use Global Variables</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/2024.html">2024</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/jpa-hibernate-stupid-performance.html">Making JPA Repository stupid fast with Entity Graph</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/docker-mod-perl.html">Running Mojolicious with <code>mod_perl</code> in Docker</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/emacs.html">Emacs</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/become-an-engineer.html">The real software path</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Noteworthy Projects</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://github.com/mollusc-labs/slapbird">SlapbirdAPM</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://github.com/rawleyfowler/Humming-Bird">Humming-Bird</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://github.com/rawleyfowler/mojolicious-Plugin-IsBot">Mojolicious::Plugin::IsBot</a>
|
||||
</li>
|
||||
</ul>
|
||||
<br />
|
||||
<div>
|
||||
<a href="http://www.gnu.org/software/emacs">
|
||||
<img src="/assets/gnu_emacs.png"/>
|
||||
</a>
|
||||
<a href="https://openbsd.org">
|
||||
<img src="/assets/openbsd.gif" style="width: 120px; height 80px" />
|
||||
</a>
|
||||
</div>
|
||||
<h2>Disclaimer</h2>
|
||||
<p>All opinions are my own, they do not reflect the thoughts expressed by my employer(s) past, present, or future.</p>
|
||||
</div>
|
||||
</body>
|
||||
<head>
|
||||
<title>rawley.xyz</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="description" value="Rawley Fowler's personal website, about Perl, Emacs and Software in General.">
|
||||
<meta name="keywords" value="Rawley Fowler rawley.xyz emacs netbsd functional clojure perl software architecture bugs fixing maker">
|
||||
<link rel="stylesheet" href="index.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="blerb">
|
||||
<p>
|
||||
Hi, I'm Rawley. I'm a full-time Husband, Dad, Emacs evangelist and Perl aficionado.
|
||||
</p>
|
||||
<p>
|
||||
I am the creator of many <a href="https://www.gnu.org/philosophy/free-sw.en.html">free-software</a> libraries and tools.
|
||||
I have extensive knowledge of Perl, Java, JVM, and Functional Programming. I'm always working on something, whether it be my
|
||||
100 year old house, or some 100 year old code.
|
||||
</p>
|
||||
<p>
|
||||
I'm always looking for interesting things to work on.
|
||||
If you have a project you think might suite me, send me an email at <strong>rawley</strong> at <strong>molluscsoftware.com</strong>
|
||||
</p>
|
||||
<h2>Blog Posts</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/posts/html-composer.html">Perl HTML Templating and HTML::Composer</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/perl-in-2025.html">Perl in 2025</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/niche-software.html">Using a niche programming language</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/dancer2-controllers.html">Dancer2::Controllers and Perl Attributes</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/perl-oo-action-benchmark.html">Perl OO benchmarks</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/maybe-escaping-evil.html">Exploring <code>evil-mode</code> alternatives</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/in-defense-of-global-variables.html">How to Properly use Global Variables</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/2024.html">2024</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/jpa-hibernate-stupid-performance.html">Making JPA Repository stupid fast with Entity Graph</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/docker-mod-perl.html">Running Mojolicious with <code>mod_perl</code> in Docker</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/emacs.html">Emacs</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/posts/become-an-engineer.html">The real software path</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Noteworthy Projects</h2>
|
||||
<div class="projects">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://github.com/mollusc-labs/slapbird">SlapbirdAPM</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://github.com/rawleyfowler/Humming-Bird">Humming-Bird</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://github.com/rawleyfowler/mojolicious-Plugin-IsBot">Mojolicious::Plugin::IsBot</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="cards">
|
||||
<a href="http://www.gnu.org/software/emacs">
|
||||
<img src="/assets/gnu_emacs.png" width="88" height="31"/>
|
||||
</a>
|
||||
<a href="http://www.gnu.org/software/emacs">
|
||||
<img src="/assets/made_with_emacs.png" width="88" height="31"/>
|
||||
</a>
|
||||
<a href="https://netbsd.org">
|
||||
<img src="/assets/powered_by_netbsd.png" width="88" height="31"/>
|
||||
</a>
|
||||
<a href="#">
|
||||
<img src="/assets/no_bad_hair_days.png" width="88" height="31"/>
|
||||
</a>
|
||||
</div>
|
||||
<h2>Disclaimer</h2>
|
||||
<p>All opinions are my own, they do not reflect the thoughts expressed by my employer(s) past, present, or future.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
48
new_post.pl
Normal file
48
new_post.pl
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Carp qw(croak);
|
||||
use HTML::Composer;
|
||||
use File::Slurp;
|
||||
|
||||
my $post_name = $ARGV[0];
|
||||
if ( !$post_name ) {
|
||||
croak "No post named provided!";
|
||||
}
|
||||
|
||||
my $h = HTML::Composer->new;
|
||||
|
||||
my $post_template = [
|
||||
head => [
|
||||
title => ["An awesome new post!"],
|
||||
meta => { name => "description", content => "Description of post" },
|
||||
meta => { name => "robots" },
|
||||
meta => { name => "keywords", content => "Awesome keywords" },
|
||||
meta => { name => "charset", content => "utf-8", charset => "utf-8" },
|
||||
link => { href => "/index.css", rel => "stylesheet" }
|
||||
],
|
||||
body => [
|
||||
a => { href => "/" } => ["<< back"],
|
||||
h1 => ["Post Title"],
|
||||
p => ["Blah blah blah"],
|
||||
h2 => ["Sub title"],
|
||||
p => ["Blah blah blah"],
|
||||
h4 => ["Related links:"],
|
||||
ul => [
|
||||
li => [
|
||||
a => { href => "https://rawley.xyz/related-content" } =>
|
||||
["Related content"]
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
my $html = $h->html($post_template);
|
||||
|
||||
print "Writing $post_name.html\n";
|
||||
|
||||
write_file( "posts/$post_name.html", $html );
|
||||
|
||||
print "DONE\n";
|
||||
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Emacs</title>
|
||||
<meta charset="UTF-8"/>
|
||||
|
||||
32
posts/fix-apache-sni-behind-alb.html
Normal file
32
posts/fix-apache-sni-behind-alb.html
Normal file
@@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Fix Apache 421 SNI Errors Behind AWS ALB</title>
|
||||
<meta content="Description of post" name="description">
|
||||
<meta name="robots">
|
||||
<meta content="keywords" name="Apache SNI Fix 421">
|
||||
<meta content="description" name="How to fix the Apache SNI issues (421 misdirected) behind AWS ALB">
|
||||
<meta charset="utf-8" content="utf-8" name="charset">
|
||||
<link href="/index.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<a href="/"><< back</a>
|
||||
<h1>Fixing Apache SNI 421 Errors Behind AWS ALB</h1>
|
||||
<h2>Understanding the Problem</h2>
|
||||
<p>
|
||||
SNI (Server Name Indicator) is a flag set in the "Client Hello" of a TLS request. It tells the server what domain you want,
|
||||
without having to decrypt the request later to get the <code>Host</code> header, or whatever else you might be using to route traffic with.
|
||||
Apache uses SNI to figure out what cert to use to decrypt the request. When SNI is missing, or Apache can't find a VHost associated
|
||||
with the domain in the SNI, it will route to the default VHost for decryption and request handling. This is now the default behaviour in 2.4.64 and up,
|
||||
it was applied to fix CVE-2025-23048. Note this is a good change, and means that Apache will reject potentially dangerous requests where SNI isn't the same as the Host header.
|
||||
</p>
|
||||
<h2>Solution</h2>
|
||||
<p>
|
||||
If you're using HTTPS on your Apache, behind an AWS ALB, you're going to run into this issue, because AWS ALB's seemingly don't set SNI at all.
|
||||
The solution is to tell Apache to relax its policy, and allow the default VHost to decrypt the message,
|
||||
and then route on the Host header to the next VHost (I think this is how it works, I could be wrong).
|
||||
You can do this with the <code>SSLVHostSNIPolicy</code> directive, setting it to <code>authonly</code> will
|
||||
return the pre 2.4.64 functionality, however it supposedly only works on 2.4.65, so you may have to skip 2.4.64.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
132
posts/html-composer.html
Normal file
132
posts/html-composer.html
Normal file
@@ -0,0 +1,132 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>HTML::Composer and Perl HTML templating</title>
|
||||
<meta content="Description of post" name="description">
|
||||
<meta name="robots">
|
||||
<meta content="Awesome keywords" name="keywords">
|
||||
<meta charset="utf-8" content="utf-8" name="charset">
|
||||
<link href="/index.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/default.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<a href="/"><< back</a>
|
||||
<h1>HTML::Composer and Perl HTML templating</h1>
|
||||
<div><small>June 25th, 2026</small></div>
|
||||
<p>
|
||||
Perl has some great templating libraries for HTML. Most of them are pretty fast, and do what you want.
|
||||
<a href="https://metacpan.org/pod/Template::Toolkit">Template::Toolkit</a> is sort of the "gold standard", and you see it most
|
||||
often in the wild. <a href="https://metacpan.org/pod/Mojo::Template">Mojo::Template</a> is the "newer" kid on the block, and is most
|
||||
associated with the <a href="https://metacpan.org/pod/Mojolicious">Mojolicious</a> framework/toolkit, if you're writing a Mojolicious application
|
||||
you're likely using Mojo::Template. There are also a few niche templating tools, like <a href="https://metacpan.org/pod/Text::Xslate">Text::Xslate</a> (unfortunately, pretty much dead), and
|
||||
<a href="https://metacpan.org/pod/Template::Tiny">Template::Tiny</a> (supported, but not seen very often). Like I said earlier, all of these libraries are great,
|
||||
you write templated text, and they give you HTML back, awesome. However, they all share a common "problem", they make me write HTML. I'm a Perl developer,
|
||||
I like writing Perl, I want to write Perl, so when I have to switch contexts to HTML it annoys me. To compound this problem, I just got off a project that used a tool called
|
||||
<a href="https://github.com/weavejester/hiccup">hiccup</a>, hiccup let me write code in its native toungue (Clojure), and get back HTML in the form of a string. This rocked!
|
||||
Not only did I not have to write HTML, it was actually <i>intuitive</i>, it provided me with a DSL for HTML. So I took this idea, and ported it to Perl, in the form of
|
||||
<a href="https://metacpan.org/pod/HTML::Composer">HTML::Composer</a>. HTML::Composer is a library that does its best to emulate that sort of intuitiveness, inside of Perl. To my surprise
|
||||
it seems to, and even more suprisingly, it performs incredibly well.
|
||||
</p>
|
||||
<h2>HTML::Composer</h2>
|
||||
<p>
|
||||
HTML::Composer only outputs HTML. It is a Perl data-structure to HTML converter, it takes an ARRAY ref, and outputs a string:
|
||||
</p>
|
||||
<pre><code class="language-perl">
|
||||
use HTML::Composer;
|
||||
|
||||
my $h = HTML::Composer->new();
|
||||
my $html = $h->html([
|
||||
head => [
|
||||
title => ["My Site"],
|
||||
script => {
|
||||
src => "/js/myScript.js",
|
||||
type => "text/javascript"
|
||||
}
|
||||
],
|
||||
body => [
|
||||
h1 => ["Hello World!"],
|
||||
br => {},
|
||||
div => { class => [ "p-3", "background-red" ] } => [
|
||||
"Hello World!", h2 => ["Test 123"]
|
||||
]
|
||||
]
|
||||
]
|
||||
);
|
||||
say $html; # <!DOCTYPE html><html> ...
|
||||
</code></pre>
|
||||
<p>
|
||||
You can also render partial HTML:
|
||||
</p>
|
||||
<pre><code class="language-perl">
|
||||
my $h = HTML::Composer->new;
|
||||
my $html = $h->partial([
|
||||
div => [
|
||||
"Hello, World!",
|
||||
a => { href => "https://www.google.com" } => ["www.google.com"]
|
||||
]
|
||||
]);
|
||||
|
||||
say $html; # <div>Hello, World!<a href="https://www.google.com"< ...
|
||||
</code></pre>
|
||||
<p>
|
||||
Since HTML::Composer operates inside of Perl data structures, and doesn't need to do any string parsing, it's quite fast. Faster than any other templating library outputting HTML I could find.
|
||||
The following benchmark is the average of five different one-hundred-million iteration runs rendering a medium sized HTML page that changed between iterations,
|
||||
with the caveat being, each of these libraries was expected to take an input scalar and output to a scalar variable (Text::Xslate is optimized to read from a file not a string, so it hated this benchmark):
|
||||
</p>
|
||||
<pre><code>
|
||||
Rate Text::Xslate Mojo::Template Template::Tiny Template::Toolkit HTML::Composer
|
||||
Text::Xslate 433/s -- -78% -93% -93% -94%
|
||||
Mojo::Template 1969/s 354% -- -69% -70% -72%
|
||||
Template::Tiny 6410/s 1379% 226% -- -1% -9%
|
||||
Template::Toolkit 6494/s 1398% 230% 1% -- -8%
|
||||
HTML::Composer 7042/s 1525% 258% 10% 8% --
|
||||
</code></pre>
|
||||
<p>
|
||||
And, while being very quick, it also performs basic HTML validations to ensure you're sending something proper (it does not make sure the tags you pass are correct, this is very expensive).
|
||||
Instead of spending time parsing and building the HTML tree, the developer has already done the work, so all we need to do is <i>compose</i> it to HTML. It also performs the necessary escapes by default, if you need to avoid escaping,
|
||||
you can use the unsafe method <pre><code class="language-perl">[ div => $h->unsafe("Stuff that shouldn't be escaped!"); ]</code></pre>
|
||||
</p>
|
||||
<h3>How it works</h3>
|
||||
<p>
|
||||
HTML::Composer uses a depth-first search, with a stack to traverse the HTML array you provide,
|
||||
based on the ordering of the data it makes assumptions about what you want, a string followed by a hash means you want to
|
||||
write a tag with some attributes, if that is then followed by an array, a tag with attributes and children. We verify if the tag
|
||||
is allowed to have children, then, we insert a reference to the current tag's scalar after the hash, and array. If a tag has no children, ie a tag with just
|
||||
a hash following, then we can finish that tag right now by pushing the HTML string output to the output array. When we encounter an array,
|
||||
simply push all of its elements onto the stack. Rinse and repeat until we encounter a scalar reference, and close the tag.
|
||||
</p>
|
||||
<h3>Optimizations + learnings</h3>
|
||||
<p>
|
||||
I learned Perl string concatenation is really slow. In the first pass at this project I used a <pre><code class="language-perl">$root</code></pre> scalar to be the final output,
|
||||
and concatenated the HTML in place, however after doing some r&d, I realised that pushing to an array, and then using Perl's <pre><code class="language-perl">join('', @array)</code></pre>
|
||||
function, was almost one order of magnitude faster. The reason this is faster, is Perl's <a href="https://github.com/Perl/perl5/blob/909c414e5450fe64ba145e6a3f3ed2e97999f060/doop.c#L666">do_join</a> function
|
||||
is highly optimized, and seems to allocate the size of string it thinks it needs ahead of time, which saves a lot of CPU time.
|
||||
</p>
|
||||
<p>
|
||||
The main logic tree uses ref and string eq's, I attempted to swap this to using regexp with a prefix <pre><code class="language-perl">ref($foo) =~ /^SC/ # SCALAR</code></pre>, this is typically how I've optimized
|
||||
logic in C code in the past, though, instead of regexp its referencing the bytes directly, which in retrospect is obviously going to be much faster than this.
|
||||
However I did expect the prefix check with regexp to be at least slightly faster, but alas it's quite a bit slower.
|
||||
</p>
|
||||
<h2>Conclusion</h2>
|
||||
<p>
|
||||
Perl has great HTML templating libraries. I hate writing HTML so I wrote one that lets me stay in Perl, and export templates via sub-routines.
|
||||
It performs really well, which is to be expected, as it does no parsing of any actual text. I hope someone else with similar pains will try it out at some point.
|
||||
Thanks for reading!
|
||||
</p>
|
||||
<h4>Related links:</h4>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://codeberg.org/rawleyfowler/perl-HTML-Composer">HTML::Composer source code</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://metacpan.org/pod/HTML::Composer">HTML::Composer</a>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Footnote: yes your eyes do not decieve you, that is codeberg, I'm going to be migrating my work off Github over the next couple weeks.
|
||||
AI was not involved in this project at all.
|
||||
</p>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
|
||||
<script>hljs.highlightAll();</script>
|
||||
</body>
|
||||
</html>
|
||||
20
posts/http2-and-perl.html
Normal file
20
posts/http2-and-perl.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>2024</title>
|
||||
<meta name="description" content="Plans for 2024" />
|
||||
<link rel="stylesheet" href="/index.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a href="/"><< back</a>
|
||||
<h1>Perl and HTTP/2</h1>
|
||||
<p>
|
||||
Perl is a great language for building applications that interface over HTTP. It has some of the best tooling for
|
||||
database access, sending/receiving HTTP requests:
|
||||
<a href="https://metacpan.org/pod/LWP">LWP</a>, <a href="https://metacpan.org/pod/Plack">Plack</a> and <a href="https://metacpan.org/pod/Mojolicious">Mojolicious</a>.
|
||||
The only glaring weakness to a Perl application as it stands, is typically, Perl servers only support HTTP/1.1. 1.1 is a "fine"
|
||||
protocol, especially for its time. However, in 2026, it's starting to show it's age. HTTP/2 isn't just "faster", it's much more efficient with your server's resources.
|
||||
It uses a single TCP socket also called a "stream" for client's to use, instead of opening multiple sockets per page load.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
20
posts/podman-rootless-on-alpine-linux.html
Normal file
20
posts/podman-rootless-on-alpine-linux.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Rootless Podman on Alpine Linux</title>
|
||||
<meta name="description" value="My experience setting up rootless podman on alpine linux">
|
||||
<meta name="keywords" value="Alpine Linux Podman OpenRC Rootless">
|
||||
<link rel="stylesheet" href="/index.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a href="/"><< back</a>
|
||||
<p>October 17th, 2025</p>
|
||||
<h1>Why I still use Perl</h1>
|
||||
<div>
|
||||
This website, my <a href="https://molluscsoftware.com">companies website</a>, and soon,
|
||||
<a href="https://github.com/perl-ide/perl-ide-poll">the Perl IDE survey</a> all run on the same
|
||||
Alpine Linux machine. My website and mollusc's website run as static-files served by <a href="https://caddyserver.com">Caddy</a>.
|
||||
In an attempt to simplify my life, I decided that the new Perl-IDE-Survey
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user