- 前回の復習
- おまじない
- 変数
- 標準入力
- 四則演算
- 基本的な演算子
- if, else文
- 論理演算子
- for文, 配列
$ plenv versions
* 5.20.2
system
plenv versions
とすることで,5.20.2
が選択されているか確認してみよう- 選択されていなければ,
plenv global 5.20.2
と実行しよう
- 選択されていなければ,
print "Hello, World!\n";
- このように書いたものを,
hello.pl
として保存します print
は, 端末に文字を出力します\n
は改行を表します- 最後に
;
を忘れずに!
$ perl hello.pl
Hello, World!
perl
の引数に実行するスクリプトファイル名を与えると, そのスクリプトを実行します
#!/usr/bin/env perl
use strict;
use warnings;
- おまじないとして, 冒頭の3行を書くようにしよう
use strict
-> 厳密な書式を定めたり, 未定義の変数を警告するといった効果がありますuse warnings
-> 望ましくない記述を警告してくれる効果があります- 以下, この資料のサンプルコードでは「お約束」を省略します
- 書かれているものとして扱ってください
use Acme::FizzBuzz;
use
の後にモジュール名を書くことで, そのモジュールを読み込んで利用する事を意味します- 前回の
Acme::FizzBuzz
のように, http://www.cpan.org/ からモジュールを入手できます- perl インストール時にデフォルトで入っているモジュールもあります
- 先程の冒頭の3行のおまじないを加えた上で,
Hello, World
という文字列を出力するhello.pl
を作成しよう- ヒント: 文字列は
"
で囲みます - ヒント: 文字列を出力する関数は
print
です
- ヒント: 文字列は
- 「変数」は, いわば「データを格納できる箱」です
- Perlの変数には, 「スカラ変数」, 「配列」, 「連想配列(ハッシュ)」という3種類の型があります
- 「スカラ変数」は, 「1つの要素しか入らない箱」と思って下さい
- 「配列」と「連想配列(ハッシュ)」は, 「複数の要素を格納出来る箱」と思って下さい
- まずは, 1つの要素を格納できる「スカラ変数」について見て行きましょう
my $hoge;
$hoge = 1;
my $foo = 3.14;
$hoge = "bar";
- スカラ変数の先頭には,
$hoge
のように$
をつけます$
はスカラ(scalar)
のs
, と覚えるとよいでしょう
=
演算子を使うことで, 左辺のスカラー変数に右辺の値を入れる(代入する)ことができます- 変数を宣言するとき(初めて使うとき)は, 先頭に
my
をつけます Perl
では, C言語やJavaのようにint
やchar
といった型がないので, 数値や文字列などを自由に代入することができます
my $hoge = 1;
print "$hoge\n"; # => 1
print '$hoge\n'; # => $hoge\n
print
を使うことで変数を出力することができます- 変数を出力する場合は,
""(ダブルクォテーション)
の中に変数を書きましょう""
の中に変数を書くと, その変数の中身が展開されて表示されます''
の中では, 展開はされず, 全てがそのまま出力されます- 変数だけでなく,
\n
などもそのまま出力されます!
- 変数だけでなく,
\n
は改行を意味します
- 自分の名前, 年齢, 身長などの情報をそれぞれ
name
,age
,height
といったスカラ変数に格納し, それらの値を出力するスクリプトprofile.pl
を作成しよう - 「お約束」の3行を忘れずに!
my $str = <STDIN>;
chomp $str;
print $str;
- 端末からPerlに対して, 標準入力を使って文字列を入力することができます
- 1行目では,
<STDIN>
で端末から文字列を入力し, 入力された文字列を変数str
に代入しています - 2行目では,
chomp
で行末の改行を削除しています
- 1行目では,
- このスクリプトを
stdin.pl
という名前で保存して, 実行してみよう
my $hoge = 4;
my $foo = 2;
my $res;
$res = $hoge + $foo # 4 + 2 = 6
$res = $hoge - $foo # 4 - 2 = 2
$res = $hoge * $foo # 4 * 2 = 8
$res = $hoge / $foo # 4 / 2 = 2
$res = $hoge % $foo # 4 % 2 = 0
$res = $hoge ** $foo # 4 の 2乗 は 16
perl
では, C言語と異なりべき乗の計算を簡単に行うことができます
my $foo = 'hoge';
my $bar = 123;
my $baz = $foo . $bar; # hoge123
print $foo . $baz . "\n"; # hogehoge123
.
で, 文字列や変数を連結することができます
my $hoge = 2 + 4 * 3; # 14
my $fuga = (2 + 4) * 3; # 18
- 演算の順序は,
()
を付けることで変更することができます- 通常の数学と同じく, Perlも足し算・引き算より掛け算・割り算の優先順位が高いです
- しかし, 2行目では
()
を付けることで足し算を先に計算させています
- 標準入力から変数を2つ読み込み, それらを四則演算(+, -, *, /)した結果を出力するスクリプト
calc.pl
を作成しよう
my $hoge = 1;
if ( $hoge == 1 ) {
print "OK\n"; # 条件が「真」の場合
} else {
print "NG\n"; # 条件が「偽」の場合
}
==
は"右辺と左辺が等しければ真"であることを意味します- 真 = 条件が正しい, 偽 = 条件が正しくない
- ここでは
$hoge
が1
と等しい場合に限り真となり,OK
という文字が表示されます $hoge
が1でなければ, 偽となるためelse
に処理が移りNG
という文字が表示されます
my $hoge = 1;
if ( $hoge == 1 ) {
print "OK\n"; # 条件が「真」の場合
}
else
の部分は省略することもできます- この場合, 条件が偽の場合(
$hoge
が1
ではない場合)は, 何の処理も行われません
- この場合, 条件が偽の場合(
== # 右辺と左辺が等しいならば真
!= # 右辺と左辺が等しくないならば真
< # 右辺より左辺が小さいならば真
> # 右辺より左辺が大きいならば真
<= # 右辺が左辺以上ならば真
>= # 右辺が左辺以下ならば真
- 数字同士を比較するときは, このような比較演算子を使います
eq == equal
ne != not equal
gt > greater than
ge >= greater equal
lt < less than
le <= less equal
- 数値を比較する場合は
==
や!=
を使うが, 文字列を比較する場合はeq
やne
といった演算子を使います- もっとも,
eq
,ne
以外はあまり使いません - 文字列の大小とは, 辞書順に並べた時に前にくるものが小さく, 後ろにくるものが大きいということです
- もっとも,
my $hoge = 'hello';
if ( $hoge eq 'hello' ) {
print "OK";
} else {
print "NG";
}
- 今回は文字列を比較しているので,
==
ではなくeq
を用いています
if ('42strings' == 42) {
print "OK\n";
}
use warnings
が有効であれば, 文字列を数値用の比較演算子で比較しようとすると, 次のような警告を出力しますArgument "42strings" isn't numeric in numeric eq (==) at reply input line 1.
- このような場合, Perlは文字列を無理やり数値として解釈して処理を継続します
- この場合, '42strings'には先頭に
42
という数値が含まれているので, Perlは==
の演算子の左辺は42
として処理を実行します - そのため, この比較は真となり, 「OK」という文字列が出力されます
- この場合, '42strings'には先頭に
if ('42' eq 42) {
print "OK\n";
}
- 逆に, 文字列の比較演算子で数値を比較しようとした場合, 警告は出力されません
- Perlは自動的に数値を文字列として解釈して,
eq
演算子の右辺は'42'
として扱われます - そのため, この比較は真となり, 「OK」という文字列が出力されます
- Perlは自動的に数値を文字列として解釈して,
- Perlには,
true
やfalse
などで真偽値を表すことはできません - そのかわりPerlでは, 次の5つの値が「偽」の値(偽値)として扱われます
- 数値「0」
- 文字列「'0'」と「''」
- 空のリスト「( )」
- undef
- そしてこれ以外の値は, Perlでは全て真として扱われます
my $hoge = 1;
if ( $hoge == 1 ) {
...
} elsif ( $hoge == 2 ) {
...
} elsif ( $hoge == 3 ) {
...
} else {
...
}
elsif
を使うことで, 分岐条件をさらに増やすことができます- PerlにはC言語の
switch
にあたるものはないので,if
/elsif
/else
で代用しましょう
- PerlにはC言語の
#!/usr/bin/env perl
use strict;
use warnings;
my $answer = 'perl'; # 好きな文字を入力しておく
- 簡単な文字当てゲーム
question_word.pl
を作成しよう - 端末から文字列を一つ入力し, その文字列が
$answer
と一致したらOK
, 外れたらNG
と表示します
&& -> かつ
|| -> または
if文
で複雑な条件を扱いたいときは,関係演算子
を用いて複数の条件を連結しましょう&&
演算子は「かつ」なので, 両方の条件が真となるときのみ真となります||
演算子は「または」なので, 条件のどちらか1つでも真となるならば真となります
my $hoge = 64;
if ( $hoge > 0 && $hoge % 2 == 0 ) {
print "&&: OK\n";
}
if ( $hoge > 0 || $hoge % 2 == 1 ) {
print "||: OK\n";
}
- 2行目は, 「64は0より大きい(真)」かつ「64を2で割った余りは0(真)」なので, 真となります
- 5行目は, 「64は0より大きい(真)」または「64を2で割った余りは1(偽)」なので, 真となります
#!/usr/bin/env perl
use strict;
use warnings;
my $answer = 1; # 好きな値を入力しておく
- 簡単な数当てゲーム
question_num.pl
を作成しよう - 端末から数字を一つ入力し, その数字が
$answer
と一致したらOK
,$answer
より大きければtoo big
, 小さければtoo small
と表示します- オプション: 入力した値が,
$answer
から-5〜+5の範囲内(例えば,$answer
が10なら, 5〜15)の場合,near
と表示するようにしてみましょう
- オプション: 入力した値が,
my @array = ( 1, "hoge", 3 );
print "@array\n"; # 1 hoge 3
- 配列を使うことで, 数値や文字列をまとめて格納できます
=
演算子を使うことで, 左辺の配列に右辺の値を代入することができます- 配列は変数名の前に
@
をつけます@
はアレイ(array)
のa
, と覚えるとよいでしょう
- 1行目の右側,
( ... )
の部分をリストと呼びます
my @array = ( 1, "hoge", 3 );
print "$array[0]\n"; # 1
print "$array[1]\n"; # hoge
print "$array[2]\n"; # 3
- 配列の一つ一つの要素にアクセスする場合は
$変数名[添字]
を使います- 添字は1ではなく0からスタートして, 1ずつ増えます
my @array = ( 1, "hoge", 3 );
print "$array[0]\n"; # 1
@変数名[添字]
ではない理由は, 「配列に格納された1つの要素」はスカラ(単一)のデータである為です- そのため, 先頭に
@
ではなく$
が付きます
- そのため, 先頭に
my @array = ( 1, "hoge", 3 );
my $sum = $array[0] + $array[2];
print "$sum\n" # => 4
- 配列の要素は普通のスカラ変数と同じように扱えるので, 代入や計算ができます
my @array = ( 1, "hoge", 3 );
print scalar @array; => 3
print $#array; => 2
- 配列を
scalar
演算子に与えると, 配列に格納されている要素の個数を取得できます @array
に対して$#array
と書くことで, 配列に格納されている最後の要素の添字を取得できます
my @array1 = ( 1, 2 );
my @array2 = ( 1 .. 5 );
my @array3 = ( @array1, 3 ); # (1, 2, 3)
()
を使うことで, 配列にをまとめて代入することができます- 連続する数字であれば, 範囲演算子
..
を使って1 .. 5
と書くことで1以上5以下
の値を配列に代入できます - 3行目のように, 数値や文字列だけでなく, 配列も組み合わせることができます
my @array1 = ( 5, 4, 3, 2, 1 );
my @array2 = reverse ( 1 .. 5 ); # OK
my @array3 = ( 5 .. 1 ); # NG
@array1
のように, 連番を逆の順番で配列に格納したい場合はreverse
を使いましょう- 範囲演算子
..
は, 必ず右側の値が左側の値より大きくなければなりません - そのため,
@array2 = ( 5 .. 1 );
のように書くと@array2
には空の要素が格納されるので注意しましょう
- 範囲演算子
my @array1 = ( 5, 4, 3, 2, 1 );
my @sorted = sort @array1; # (1, 2, 3, 4, 5)
sort
を使うと, 配列の要素を並び替えますsort { $a <=> $b }
と書くと, 数値としてソートしますsort { $a cmp $b }
, あるいはsort
のみを書くと, 文字列としてソートします
- 変数
$a
と$b
はsortで使う為に予約されているので, sort以外で使ってはいけません
my @array = ( 1, "hoge", 3 );
for my $var ( @array ) {
print "$var\n";
}
- 配列の中身を走査するのに,
for
文がありますforeach
と書いても問題ありません. 実はPerlの内部では, 同じように処理されます
- この場合, 変数
$var
に$array[0]
,$array[1]
... という値が順番に代入され, 処理が行われます
my @array = ( 1, "hoge", 3 );
for ( my $i = 0; $i < scalar @array; $i++ ) {
print "$array[$i]\n";
}
$#array
は,@array
の最大の添字を表します -この場合,@array
には3個の要素が格納されているので,$#array
は2となります- よほどの事がないかぎり, この方式の
for
は使いません!- 先ほど紹介したforループで大抵事足りる為です
my @array = ( 1, "hoge", 3 );
for my $i (0 .. scalar @array - 1) {
print "$array[$i]\n";
}
- 先ほどのC言語風のforループは, 範囲演算子を利用してこのように記述することができます.
- 結構便利なので覚えておきましょう!
- 配列
@array
に<STDIN>
を使って3つの文字列を格納し, これを「文字列として」ソートしたものを出力するsort.pl
を書いてみよう- オプション:
@array
に文字列を3個入力する処理は,<STDIN>
を3回書くのではなく, for文を使ってシンプルに書いてみよう
- オプション:
FizzBuzz
問題にチャレンジ!!- 1から100までの数字について, その数字が
3
で割り切れるならFizz
,5
で割り切れるならBuzz
,3
でも5
でも割り切れるならFizzBuzz
, それ以外ならばその数字自身を出力するfizzbuzz.pl
を作成しよう
- 1から100までの数字について, その数字が
-
https://github.com/perl-entrance-org/workshop-2014-02/blob/master/practice.md
- 今回の内容を復習することができる問題集です
- ご不明な点があれば, 気軽にスタッフまでお尋ねください