An Intro to

William Lindley — [email protected]

A Modern

● Remember Analogies from your SATs?

Mojolicious : :: Rails : Ruby

● But wait, why Perl 5? Isn't Perl 6 out? ● A brief sidebar on ● An example or two ● Installing Perlbrew and Mojolicious ● You first Lite program and Awayyy you go

Perl 5, Perl 6: Different animals

● Perl 6, announced in 2000, is actually a separate language. Most likely to be renamed “Raku” in the near future. ● 2019-06-10 — Perl 5.30 was released. ● Perl 5 continues development stronger than ever

Perl: Baked In Unicode

● Supports UTF-8 and other stream types in addition to ASCII ● UTF-8 is self-synchronizing: can find code point boundaries without reading from the beginning of the string.

Unicode in Perl

● use utf8; # at start of file tells Perl the source code is in Perl. ● use v5.14; # or higher tells Perl to process strings internally as Unicode logically- wide characters ● Using Mojolicious does both of the above ● open FH, ">:utf8", "file"; opens a file (stream) with Unicode encoding layer ● binmode(STDOUT, ":utf8"); reopens standard output with Unicode encoding

Seamless Unicode use v5.14; use utf8; binmode(STDOUT,":utf8"); use Unicode::Collate; my @words=qw(crow cräme cream crême); print join(' ', Unicode::Collate-> new->sort(@words));

→ cräme cream crême crow

First-Class Characters

● As a Perl one-liner

$ perl -e 'use v5.14; use charnames ":full"; binmode(STDOUT,":utf8"); print "\N{SNOWMAN}"' ☃ $ ● More at http://www.unicode.org/charts/charindex.html ● Use them in routes (URLs) in Mojolicious! http://example.com/☃

Mojo: Rapid development

● http://mojolicious.org/ ● Programs using Mojolicious::Lite, the same code with a few added shortcuts, can easily be turned into complete systems (“apps”) ● Built-in: RESTful routes, plugins, command-line interfaces, Perl-ish templates, automated tests, session management, form validation, static file server…

Easy to create and deploy

● Auto-detects standalone or PSGI (with Apache or Nginx) ● Servers: Development auto-reloads source; or: – Fast non-blocking server for small to mid-sized applications – Multi-threaded deployment server ● Instant TLS and WebSocket support ● JSON, HTML/XML parser, CSS selector support…

One-Liners

● Use the 'ojo' module with Perl command line perl -Mojo -E'say g("drudgereport.com") ->dom("font[size=+7]")->first ->all_text' STRENGTH: HK PROTESTERS DEFY POLICE

One-Liners, Part II

● perl -Mojo -E "say g('https://fastapi.metacpan.org/v1/ release/Mojolicious')->json- >{version};" 8.25

Functions for One-Liners

● a Create a Mojolicious::Lite 'app' ● b Turn string into a Mojo::ByteStream object. ● Turn list into a Mojo::Collection object. ● , h, o, t, u Perform DELETE, HEAD, OPTIONS, PATCH, PUT request ● f Form POST ● g, p Perform GET, POST request with "get" in Mojo::UserAgent and return resulting Mojo::Message::Response object. ● j Encode Perl data structure, or decode JSON with Mojo::JSON. ● Print using Data::Dumper ● w Websocket ● x Turn HTML/XML input into Mojo::DOM object.

Three line web application

use Mojolicious::Lite; get '/' => {text => 'Hello World!'}; app->start; ● Then run it with: $ morbo hello.pl Server available at http://127.0.0.1:3000. $ curl http://127.0.0.1:3000/ Hello World!

Parallel Requests

● Event Loops and Callbacks ● And you thought you needed Node.JS for this?

my $callback = sub { print shift->res->body; }; $client->get('http://mojolicious.org' => $callback); $client->get('http://metacpan.org' => $callback); $client->start;

Non-blocking, Sequential. Event loop continues to run. get('https://mojolicious.org')->then(sub { my $mojo = shift; say $mojo->res->code; return get('https://metacpan.org'); })->then(sub { my $cpan = shift; say $->res->code; })->catch(sub { my $err = shift; warn "Something went wrong: $err"; })->wait;

Promises: Synchronize non-blocking operations (all) # Mojo::Promise is a Perl-ish implementation of # Promises/A+ and a superset of ES6 Promises. my $mojo = get('https://mojolicious.org'); my $cpan = get('https://metacpan.org'); Mojo::Promise->all($mojo, $cpan)->then(sub { my ($mojo, $cpan) = @_; say $mojo->[0]->res->code; say $cpan->[0]->res->code; })->catch(sub { my $err = shift; warn "Something went wrong: $err"; })->wait;

Mojo::DOM, the XML parser use Mojo::DOM; my $dom = Mojo::DOM->new('

Test

'. '

123

'); # Parse say $dom->at('#b')->text; # Find say $dom->find('p')->map('text')->join("\n"); say $dom->find('[id]')->map(attr => 'id')→join("\n"); # Iterate $dom->find('p[id]')->reverse->each(sub { say $_->{id} }); for my $e ($dom->find('p[id]')->each) { say $e->{id}, ':', $e->text; } # …and, modify: $dom->find('div p')->last->append('

456

'); $dom->find(':not(p)')→map('strip'); # CSS3 selector

Websocket Example in One File

use Mojolicious::Lite -signatures;

# Render template "index.html.ep" from the DATA section get '/' => {template => 'index'};

# WebSocket service used by the template to extract the title from a website '/title' => sub ($c) { $c->on(message => sub ($c, $msg) { my $title = $c->ua->get($msg)->res->dom->at('title')->text; $c->send($title); }); }; app->start; __DATA__

@@ index.html.ep % my $url = url_for 'title';

More Mojo Modules

● Mojo::Pg for PostgreSQL Mojo::SQLite ● Mojolicious::Command::* for writing command-line interfaces ● Mojo::UserAgent::Server and Mojo::EventEmitter Roll your own HTTP/HTTP-like server

Perlbrew — Easy Development Independent of Your System Perl

● http://perlbrew.pl/ ● Simple install: – \curl -L http://install.perlbrew.pl | bash (or) – sudo cpan App::perlbrew – perlbrew init

Perlbrew

● Manage multiple perl installations under your $HOME directory. ● Individual users or web applications operate independently ● Self-compiled (once!) to fit your system perfectly ● Don't need sudo to install modules (Pro: Can keep multiple versions across system for compatibility; Con: Each user's copy of perlbrew and modules must be updated separately when required)

Perlbrew is simple

● To install the latest stable release, and use it permanently: perlbrew install perl-5.30.0 perlbrew switch perl-5.30.0 ● All this requires only one extra line appended to ~/.bash_profile : source ~/perl5/perlbrew/etc/bashrc

Get your Mojo on

● Installable directly with Perlbrew ● Only Perl 5 dependencies ● http://mojolicious.org/ ● One-line install: $ curl -L https://cpanmin.us | perl - -M https://cpan.metacpan.org -n Mojolicious ● Small, lightweight, well-documented

Your first Lite 'app'

$ mojo generate lite_app first [exist] /home/bill/demo [write] /home/bill/demo/first [chmod] /home/bill/demo/first 744

Program file: first

#!/usr/bin/env perl @@ index.html.ep use Mojolicious::Lite; % layout 'default'; % title 'Welcome';

Welcome to the Mojolicious get '/' => sub { real-time web framework!

my $c = shift; $c->render(template => @@ layouts/default.html.ep 'index'); }; <%= title %> app->start; <%= content %> __DATA__

Let's run it

$ morbo first -l http://localhost:4000

An Intro to Mojolicious

William Lindley

http://wlindley.com [email protected] 480-947-6100