class: title, smokescreen, shelf, no-footer # Perl入学式 #01-03 補講 <div class=footnote> <small> Copyright 2019,2022 (C) Ken'ichi Fukamachi (<A HREF=https://www.fml.org/>fml.org</A>), CC BY-NC-SA </small> </div class=footnote> --- class: compact layout: false # 復習: 概要 - C言語 - Unixオペレーティングシステムを書くために必要十分な小さい言語 - コンパイル言語です - /\* から \*/ の中がコメント(今では各行の//より右側もコメント)です - シェル - Unixを制御するしくみで、入力したコマンドを解釈しています - スクリプトに書かれた命令を一行ずつ実行することもできます - スクリプト言語の御先祖、スクリプト言語流行のエンジン第一段 - 各行、`#`の右側は、コメントです - ひとつの言語ではなく、**小さな言語とUnixコマンド群の総計**がシェルです - Perl - シェルの進化系、Unix上で、より便利な処理を追求した言語 - スクリプトないしはLL言語を流行させたエンジン第二段です - 正確には行単位ではなく最適化後に実行しています(半コンパイル言語(?)) - 各行、`#`の右側は、コメントです - 1行ハック(one liner)が得意(たいていPerlが適切になんとかします) - 正規表現といえばPerl、他の言語もPerlに合わせる事実上の標準 --- class: compact layout: false # 復習: 変数 - C言語 - 変数名は、英数字と_の組み合わせが基本です。 変数は基本小文字、定数は大文字にするなどの慣例があります - 空白の長さは自由なのでコードが読みやすくなるように使ってください - 変数には種類(型)があり、明示的に使い方を指示する必要があります - シェル - 変数名のルールは特別ないと思いますがC準拠の気がします - Unixの設定ファイル等ではデータ構造の区切りを空白で表現します。 Excelの升目と同じですが、升目のかわりに空白です。 空白のあつかいをまちがうと、 データの処理単位が変わってしまうので気をつけましょう。 - 空白の長さは自由ですが、シェル特有の**例外**があります - **値の代入**の際、**空白を入れてはいけません**。 例: ` x=1` - **値を参照**する時は**`$`が必要です** 例: `echo $x` - 変数は1種類、スカラー(文字列)のみ - Perl - C準拠ぽいですが、大文字の使い方にPerl特有の慣例が少しあります - 変数には常に**`$`などの種類を示す記号(シジル)**が必要です。例: `$x` - 変数の種類は、スカラー(文字列と数字)、配列、ハッシュがあります --- class: compact # 例題: じゃんけん - シェル入学式シーズン1第一回の最終課題を Perl で書いてみましょう。 - ファイル名は janken.pl とします。 以下の課題では、このファイルを改造し続けていく想定です - じゃんけんの仕様は次のとおりです - ぐーは0、ちょきは1、パーは2と表現することにします - **`3 + 自分の手 - 相手の手`を3で割った余り**が勝ち負け判定です - 判定は**0があいこ、1が敗け、2が勝ち**になります、確認してみてね - まずは以下の見本を見ながら janken.pl を作成してください - [模範解答](examples/janken_01__template.pl.txt) --- class: compact # 例題: じゃんけん (入力) - 自分の手を入力できるようにしてください - キーボードから変数 $jibun へ入力したいわけですけど、何を使うんでしたっけ? - `<STDIN>`から読むんですよね〜 - あと chomp も使いますよ - [模範解答](examples/janken_02__input.pl.txt) --- class: compact # 例題: じゃんけん (条件文) - 判定結果が数字だとなんだかわかりません(@_@)、最後の出力(print してる)部分を改造しましょう。 結果を数字ではなく「あいこ」「負け」「勝ち」と表示してください - Perlの条件文は `if () { ... } elsif () { ... } else { }` です。気をつけましょうね、 `if .. else if ... else`(それはC言語) でも `if elif fi`(それはシェル) でもありません ``` if ( 条件1 ) { ... } elsif ( 条件2 ) { ... } else { ... } ``` - [模範解答](examples/janken_03__if.pl.txt) --- class: compact # 例題: じゃんけん (条件文+乱数) - 相手の手はコンピュータに決めさせます - 乱数は次のような呪文を書いてください、意味を調べるのは自由課題とします ``` # 乱数の初期化 srand(time|$$); # 相手の手(0か1か2)をコンピュータに決めさせる my $aite = int(rand(3)); ``` - 少し、ゲームらしくなってきました - [模範解答](examples/janken_04__random.pl.txt) --- class: compact # 例題: じゃんけん (三回やる) - いままでは一回しか出来ませんでした。 - 3回じゃんけんができるようにしてください - 範囲指定子(`1..3 `)を使って3回実行することにしましょう - `for (1..3) { ... }`で3回ループ内を実行しますよ、おぼえているかな? - [模範解答](examples/janken_05__for.pl.txt) ``` 【実行例】 1 負けです 2 あいこです 3 負けです ``` --- class: compact # 例題: じゃんけん (配列で履歴をとる) - 配列に履歴をとっていきましょう - 「自分」「相手」が何を出したか(数字)を配列に入れていきます - 「判定結果」は数字ではなく日本語を記録していきましょう - 配列の中身は数字でも文字列でも同じように書いてOKです。 Perlが、よろしくあつかってくれますよ - [模範解答](examples/janken_06__array.pl.txt) ``` 【実行例】 1 負けです 2 あいこです 3 負けです [じゃんけんの履歴] 1 0 負け 2 2 あいこ 3 2 負け ``` --- class: compact # 例題: じゃんけん (ハッシュで履歴をとる) - 勝敗の結果の統計情報を表示してください - ハッシュの**うれしい便利な**使い方です。 - 配列と違い、ハッシュのキーは、なんでもいいことに注意しましょう - 文字列「あいこ」「勝ち」「負け」をキーに使えます。 これで簡単に統計が取れますよね? というか、こういう使い方をしないとハッシュのうれしさが伝わりません - [模範解答](examples/janken_07__hash.pl.txt) ``` 【実行例】 ...じゃんけんの様子は省略... [勝敗の統計] あいこ 1 勝ち 2 ``` --- class: compact # 例題: じゃんけん (数字以外を入れたら停止) - 仕様 - 回数無指定つまり無限回のじゃんけんにしてください - キーボードから数字(例: 英文字, 特殊文字)以外を入力したとき、ゲームは終了します - 上限不明の場合の**くり返し文**は while が便利です - 無限ループは `while (1) { ... }` と書いてください - last コマンドでループが止まります - そして、入力判定は**正規表現**の出番です! - 入力文字列が**数字**以外という正規表現は、どう書くでしょうか? - if文をたくさん書いても実現できますけど、正規表現なら一行ですよね? このあたりが正規表現のうれしいところです - [模範解答](examples/janken_08__while.pl.txt)