class: title, smokescreen, shelf, no-footer # Perl入学式in千歳 第5回 <div class=footnote> <small> Copyright 2019,2022 (C) Ken'ichi Fukamachi (<A HREF=https://www.fml.org/>fml.org</A>), CC BY-NC-SA. (注: <A HREF="/slides/lang/perl/caution/">諸注意から始めてね</A>) </small> </div class=footnote> --- name: index class: compact # お品書き 1. [環境構築/環境確認](#env) 1. [Webの基礎](/slides/web/intro/) 1. [Web APIの基礎](/slides/web/api/janken/) 1. このスライド - [クライアント側(CLI)の作成](#frontend) - [バックエンド側の作成](#backend) 1. 時間があれば自由課題/発展課題 - フロントエンド側の見栄えをなんとかする方向(HTML5とかJSへ) - バックエンド側を改造...たとえば対戦モード? 1. 議論/相談 - 夏休み中にAPIサーバを改造するとか? slackでサポート, 個人戦でなくてもいい気が? - 秋学期直前に締めの回がある?(10/01あたりか?) <div class=footnote> <small> (脚注) 今回は、インターネット接続が必須です </small> </div class=footnote> --- name: frontend name: env class: title, smokescreen, shelf, no-footer # 環境構築/確認 <div class=footnote> <small> (脚注) 今回は、インターネット接続が必須です </small> </div class=footnote> --- class: compact # Mojoliciousモジュールを使いたい - 今回はPerlのWebフレームワークMojoliciousモジュールを使ってAPIサーバを製作します。 このモジュールをインストールしてください - WSL環境(ubuntuつまりdebianファミリー)のパッケージシステムにMojoliciousがあるので、 次のように`apt install`してください。これで準備完了です ``` sudo apt install libmojolicious-perl ``` - 参考文献: [Mojolicious入門(Perlゼミ)](https://mojolicious.perlzemi.com/) - Webの基礎的な解説をするので、いったん[目次](#index)へもどります --- name: frontend class: title, smokescreen, shelf, no-footer # Webクライアントの製作<br>フロントエンド側(CLI) --- class: compact # [再掲]HTMLとCGIの仕組み(janken API, 全体像, 静的)  --- class: compact # curlコマンドを使ったCLIでのデバッグ 次の文字列をwslのターミナルに打ちこみEnterしてみましょう ``` curl -X POST -d jibun=2 http://ise.ex2022.fml.org/api/janken/v2 ``` - じゃんけんAPIサーバのURLが`http://ise.ex2022.fml.org/api/janken/v2` - HTTPのPOSTメソッドを使い(`-X POST`オプション) - `-d ...`の部分が送りたい「キーと値の組」の指定 - キーが`jibun`, 値が`2` ``` # ハッシュ(連想配列)を使って書けば、こういうイメージ %key_value_data = ( jibun => 2, ); ``` --- name: curl.pl class: compact # [例題] curl.pl <div class=footnote> <small> </small> </div class=footnote> ``` #!/usr/bin/env perl use strict; use warnings; use HTTP::Tiny; # カスタマイズできる部分 my $url = "http://ise.ex2022.fml.org/api/janken/v2"; my $data = {jibun => 2}; # hash reference (飛ばした内容) # MAIN (HTTP呼び出し本体) my $http = new HTTP::Tiny; # インスタンスを生成 my $r = $http->post_form($url, $data); # POSTメソッドでCGI FORMデータを送る print $r->{content}, "\n"; # サーバからの返事$rの本体を表示 ``` ``` [実行例] <html><body> [2,2,0] # comment omitted ... </body></html> ``` --- class: compact # 解説: hash reference (1) <div class=footnote> <small> </small> </div class=footnote> ``` my %data = ( # これはハッシュ(連想配列) jibun => 2 # KEYがjibun, VALUEが2;いわゆるKEY-VALUE ) my $data = \%data; # \をつけるとリファレンス、代入先は $data # いっきにリファレンスの変数 $data 宣言と初期化(上の合計4行と同じ意味) # 右辺に { ... } と書くことで Perl は hash reference と分かってくれる my $data = { jibun => 2 }; ``` - ハッシュ(連想配列)を便利に使う方法として、こういう別の書き方があります - **一つの塊を、どーんと渡せます**。 **関数呼び出しの際に便利なので多用**されます - 引数で配列や連想配列を渡し(例: `post_form(%data)`)ても動きますが、 関数側で配列に展開されてしまい、 コードが書きにくいのです。**まとめておいてほしい**の ;-) - これはC言語でいうところの**構造体へのポインタ**に相当するものなのですが、 長い説明が始まるので、こういうもんだということで進んでしまいます --- class: compact # 解説: hash reference (2) ``` my $http = new HTTP::Tiny; # インスタンスを生成 my $r = $http->post_form($url, $data); # POSTメソッドでCGI FORMデータを送る print $r->{content}, "\n"; # サーバからの返事$rの本体を表示 ``` - この部分ですが、post_form関数の引数で`$data`を渡しています - ちなみに`$url`は文字列のスカラー変数、`$data`はハッシュリファレンス - post_form関数の返す値はハッシュリファレンスです。これを`$r`に代入 - 最後の`$r->{content}`は、連想配列のキー`content`の値を意味する書き方です。 このcontentにAPIサーバがHTTPで返してきたデータ(HTML)が格納されています --- class: compact # 解説: hash reference (3) <div class=footnote> <small> </small> </div class=footnote> - ハッシュリファレンス$rの中身をすべて書くと、こうなっています ``` $r = { 'url' => 'http://ise.ex2022.fml.org/api/janken/v2', 'reason' => 'OK', 'protocol' => 'HTTP/1.1', 'success' => 1, 'status' => '200', 'content' => '<html><body> [2,1,2] # comment omitted ... </body></html>', 'headers' => { 'content-type' => 'text/html;charset=UTF-8', 'connection' => 'keep-alive', 'server' => 'nginx/1.22.0', 'content-length' => '57', 'date' => 'Sat, 23 Jul 2022 02:53:31 GMT' } }; # Data::Dumperモジュールを使い中身を表示しています(debugの定番) ``` --- class: compact # 解説: オブジェクト指向風の書き方 ``` # いわゆるコンストラクタです。書式は言語によっていろいろ インスタンス = new モジュール名; # C++風に呼び出せます(呼び出す先は「モジュール::メソッド」と解釈) インスタンス->メソッド(引数); my $http = new HTTP::Tiny; # インスタンスを生成 my $r = $http->post_form($url, $data); # POSTメソッドでCGI FORMデータを送る ``` - Perlはオブジェクト指向言語ではありません。 「好きなように書けばいいじゃん」でお馴染みのLarry Wallなので、 Perl 5では**オブジェクト指向風の書き方も提供**しています (つまりオプションです)。ただ、 多くのモジュールが、 この形式を使えるように作られているので、 このC++風の書き方が普通です。 - こういうふうに書けば便利にHTTP::Tinyモジュールが使える!と理解するだけでok --- name: backend class: title, smokescreen, shelf, no-footer # janken APIサーバの製作<br>バックエンド側 --- class: compact # 課題 <div class=footnote> <small> </small> </div class=footnote> - じゃんけんプログラムにMojoliciousを組み込んで、APIサーバにしてください - 変更点は2つ - Webサーバ化すること - 入力を読むところが、キーボードではなくCGI (CGI経由で変数jibunの値を読み込みます)