Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Perlブートキャンプ
Search
Hatena
November 14, 2025
Technology
0
130
Perlブートキャンプ
2025-11-14 YAPC::Fukuoka 2025
Hatena
November 14, 2025
Tweet
Share
More Decks by Hatena
See All by Hatena
はてなサマーインターンシップ2025 Web API 講義資料
hatena
0
560
はてなサマーインターンシップ2025 フロントエンド 講義資料
hatena
18
8.3k
はてなサマーインターンシップ2025 コンテナ + Kubernetesハンズオン 講義資料
hatena
0
330
はてなサマーインターンシップ2025 クラウドと運用 講義資料
hatena
0
320
はてなサマーインターンシップ2025 RDBMSの基礎 講義資料
hatena
0
360
はてなサマーインターンシップ2025 セキュリティ 講義資料
hatena
0
360
はてなサマーインターンシップ2025 AIエージェント活用 講義資料
hatena
1
1.9k
はてなサマーインターンシップ2025 プロダクトマネジメント 講義資料
hatena
0
360
【詳説】コンテンツ配信 システムの複数機能 基盤への拡張
hatena
0
580
Other Decks in Technology
See All in Technology
クレジットカードの不正を防止する技術
yutadayo
17
7.6k
大規模モノレポの秩序管理 失速しない多言語化フロントエンドの運用 / JSConf JP 2025
shoota
0
160
re:Invent完全攻略ガイド
junjikoide
1
360
ステートレスなLLMでステートフルなAI agentを作る - YAPC::Fukuoka 2025
gfx
8
1.3k
Spring Boot利用を前提としたJavaライブラリ開発方法の提案
kokihoshihara
PRO
2
220
AIでテストプロセスを自動化しよう251113.pdf
sakatakazunori
0
150
AIを前提に、業務を”再構築”せよ IVRyの9ヶ月にわたる挑戦と未来の働き方 (BTCONJP2025)
yueda256
1
740
[CV勉強会@関東 ICCV2025] WoTE: End-to-End Driving with Online Trajectory Evaluation via BEV World Model
shinkyoto
0
270
AWS資格は取ったけどIAMロールを腹落ちできてなかったので、年内に整理してみた
hiro_eng_
0
230
Javaコミュニティの歩き方 ~参加から貢献まで、すべて教えます~
tabatad
0
120
「O(n log(n))のパフォーマンス」の意味がわかるようになろう
dhirabayashi
0
180
LINEスキマニ/LINEバイトにおけるバックエンド開発
lycorptech_jp
PRO
0
190
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
355
21k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
8.1k
Context Engineering - Making Every Token Count
addyosmani
10
390
For a Future-Friendly Web
brad_frost
180
10k
Into the Great Unknown - MozCon
thekraken
40
2.2k
Code Review Best Practice
trishagee
72
19k
jQuery: Nuts, Bolts and Bling
dougneiner
65
8k
Scaling GitHub
holman
463
140k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
48
9.8k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
11
930
Transcript
Perl ブートキャンプ id:onk 2025-11-14 YAPC::Fukuoka 2025 1
元ネタ: はてなインターン講義資料 2 2 特に最後にブートキャンプ講義を 担当した id:anatofuz
$self • 大仲 能史 a.k.a. id:onk • 芸歴20年目 • 株式会社はてな
• チーフエンジニア 3
4 Perl 読んだこと/書いたこと ありますか?
5 Perl?
Perl? Perl(パール)とは、ラリー・ウォールによって開発され たプログラミング言語である。実用性と、多様性を重視し ており、C言語やsed、awk、シェルスクリプトなど他の プログラミング言語の優れた機能を取り入れている。 ウェブ・アプリケーション、システム管理、テキスト処理 などのプログラムを書くのに広く用いられている。 6
Perl? • Goと違って、コンパイルをしないインタプリ タ型言語 ◦ Better shell としても使えるし、ウェブアプリケー ションを書くことだってできる •
素早いウェブ開発の道具として、古くから人 気のLightweight Language ◦ はてな/DeNA/Mobile Factory/mixi/LINE... 7
Perl? • Perl == Perl5 ◦ 偶数が安定版、奇数が開発版 • Perl6がリリースされた時期もあった ◦
今はRakuという別言語になっている ◦ Perl5とPerl6(Raku)はJavaとJavaScriptくらいの差 がある 8
Perl? • はてなでは今も元気に使っている ◦ HTMLのテンプレートエンジンとして(Xslate) ◦ GraphQLサーバーとして • 他にもUNIXではよく使われている ◦
git ◦ Linux ◦ LaTeX 9
10 今日のゴール
11 1時間強で 「Perl完全に理解した」 になる
ゴール 12 のはもちろん難しいので... • 既存のコードを読むための取っ掛かりが作れ るようになる ◦ 困ったときのインデックスとして ◦ AIに聞くにも最低限の情報を持っていると便利
• 周りのコードを参考にできる=書ける
Perlコードはこんな見た目 package Example::Greeter; use v5.42; sub greet { my ($class,
$what) = @_; say "Hello, $what!"; } 13 • モジュール ◦ 拡張子は.pm
Perlコードはこんな見た目 14 • メインスクリプト ◦ 拡張子は.pl • 実行 $ perl
hello.pl Hello, World! use v5.42; use lib 'lib'; use Example::Greeter; Example::Greeter->greet('World');
15 Perlに触れていく前に...
ドキュメントはperldocで引く $ perldoc Carmel # モジュール (後述)のドキュメント $ perldoc -f
print # 組み込み関数は -f $ perldoc -v @_ # 組み込み変数は -v $ perldoc perl 16
CPAN • The Comprehensive Perl Archive Network ◦ https://metacpan.org/ •
世界中のさまざまなPerlモジュールが集まっ ている • Perlの言語的な強みの一つ=コミュニティ 17
Carmel, Carton • Rubyで言うBundler ◦ cpanfile, cpanfile.snapshotで依存を管理して ◦ carmel exec
...で実行する • プロジェクトのlocal/に展開して使う ◦ vendor/bundleと思えばOK 18
Perlとコミュニティ • 日本でPerlが流行った理由の1つにコミュニ ティがある ◦ なんとか.pmを始めた (Perl Mongers) • アドベントカレンダー文化はPerlコミュニ
ティ由来 ◦ https://perl-users.jp/articles/advent-calendar/ 2008/ 19
Perlとコミュニティ • YAPC::Japan ◦ Yet Anotherな草の根カンファレンス ◦ YAPC::Asiaの後継としてリブート • TPRC
◦ The Perl and Raku Conference ◦ Formerly known as YAPC::NA 20
21 Perlの環境
非常に高い後方互換性 互換性を失った先は狂気です 後方互換性よりもはるかに高い「後方『バ グ』互換性」を守ってきました perldoc perlpolicy 22
Perlバージョン • おそらくよく使われていたのはv5.8やv5.10 ◦ 2002-2010 ◦ CentOS 6のPerlが最後までv5.10.1だったはず • v5.12からは毎年リリースしている
◦ 現在v5.42 23
Perlバージョン • 公式にサポートすると謳っているのは 最新2つの安定バージョンのみ ◦ 今ならv5.42とv5.40 • コミュニティ的にはv5.10も保守しているこ とが多い ◦
Rubyで言うと1.9が出た時期 ◦ さすがにv5.10は凄くてv5.16ぐらいをよく見る 24
Perlバージョン • 最近は新しい書き方を取り入れている ◦ built-in Boolean、defer、class構文、... • バージョン指定によって動きが変わる ◦ use
v5.42; の行 ◦ よりよいデフォルト値に 25
よりよいデフォルト値 • 古い定型文が減る方向に ◦ use strict; use warnings; ◦ use
strictはJSにも輸出された プラグマ ▪ 互換性を壊さずに進化するため • 良いfeatureを有効にする ◦ say, module_true, isa, try, ... 26 use v5.42; # 以下の記述と同じ use warnings; use strict; no feature ':all'; use feature ':5.42';
use strict; use warnings; 27 • ファイルの先頭には必ず書きましょう my $message =
"hello"; print $messsage; # typo! # => エラーにならない! $messagge = "bye"; # typo! # => $messagge がグローバル変数になる!
前半戦 リファレンス見れば載ってるので 体力温存しながら聞いて 28
29 データ型
データ型 • スカラー • 配列 • ハッシュ 30
データ型 > シジル • $scalar, @array, %hashの記号がつきます ◦ S/$, a/@,
H/% が似てる、で覚えるらしい 31
データ型 > スカラー • 「1つの値」 • 文字列や数値、Bool、リファレンス 32
• Defined ◦ Ref ▪ ArrayRef ▪ HashRef ▪ ScalarRef
▪ CodeRef ▪ RegexpRef ▪ GlobRef ▪ FileHandle ▪ Object データ型 > スカラー 33 • Bool • Undef • Defined ◦ Value ▪ Str • Int
データ型 > 配列 • いわゆる配列です ◦ my @array = (1,
2, 'foo', 'bar'); • 1要素を取り出すときは$でアクセス ◦ my $elem = $array[2]; ◦ 超絶に分かりづらいと思う ▪ $arrayも同時に存在できるので死 ▪ 普段は直接配列を扱わずにArrayRefを使う(後述)ので 今は流してくれ 34
データ型 > 配列 • 複数要素を取り出すときは@ ◦ my @foo = @array[1,2]
• 分割代入もできます ◦ my ($one, $two, @rest) = (1, 2, 'foo', 'bar'); ◦ my ($foo) = @array; は先頭要素を取り出している 35
データ型 > 配列 36 • 基本操作たち $array[0]; # get $array[1]
= 'hoge'; # set my $length = scalar @array; # 長さ my $last_idx = $#array; # 最後の添字 my @slice = @array[1..4]; # スライス for my $e (@array) { # 全要素ループ print $e; }
データ型 > 配列 • 最後の添字って何 ◦ こういう使い方でeach_with_index的で便利 37 my @array
= ('apple', 'banana', 'cherry'); my @result = map { "$_: $array[$_]" } 0..$#array; # => ('0: apple', '1: banana', '2: cherry')
データ型 > ハッシュ • key, valueの組です ◦ my %hash =
(foo => 1, bar => 2); • 取り出すときは $hash{foo} ◦ =>の左や{}の中はbare wordが許される 38
データ型 > ハッシュ • 配列との相互変換ができる ◦ my @array = %hash;
◦ my %hash = @array; • => はfat commaと呼ばれる ◦ my %h = (foo, 1) と my %h = (foo => 1) が同じ ◦ hashにするときは要素が偶数じゃないとwarn 39
データ型 > ハッシュ • 配列と何が違うの ◦ 順序じゃなくキーでアクセスしたい、がそもそもの差 ◦ my $name
= $hash{name}; • 代入時に何 ($, @, %) に入れるかが大事 40
データ型 > ハッシュ 41 • 基本操作たち $hash{perl}; # get $hash{perl}
= 'larry'; # set for my $key (keys %hash) { # 全要素のキー my $value = $hash{$key}; # キーで各要素を get }
データ型 > 真偽値 42 • falseや0、空文字はfalsy ◦ "0" もfalsy •
空リストもfalsy ◦ スカラーコンテキストで0になる(後述) • 他はtruthy
43 リファレンス
リファレンス • 素の配列やハッシュは素朴なリスト過ぎる ◦ 配列もハッシュも、スカラーしか持てないため、 複雑なデータ構造を作れない • 基本的にArrayRef, HashRefで生活します 44
リファレンス > ArrayRef 45 • 入れ子の行列を作ってみるか... my @matrix = (
(0, 1, 2, 3), (4, 5, 6, 7), );
リファレンス > ArrayRef 46 • このコードは配列の合成になる ◦ リストを入れ子にできない my @matrix
= (0, 1, 2, 3, 4, 5, 6, 7);
リファレンス > ArrayRef my @array = ('a', 'b', 'c'); my
$ref = \@array; # @array へのリファレンス my $ref = ['a', 'b', 'c']; # 上記の略記。 # ちなみに \('a', 'b', 'c') は別物 47
リファレンス > ArrayRef # 2つのArrayRefをもった(長さ2の)配列 my @matrix = ( [0,
1, 2, 3], [4, 5, 6, 7], ); 48
リファレンス > ArrayRef 49 # 普段はArrayRefの中にArrayRefを入れる # ArrayRefはスカラーなのでシジルが $ に
my $matrix = [ [0, 1, 2, 3], [4, 5, 6, 7], ];
リファレンス > ArrayRef 50 # デリファレンス my @array = @$ref;
# 頭に @ をつけて配列に戻す # もしくは my $scalar = $ref->[1]; # -> を使って直接要素を取り出す • リファレンスから値を取り出す
my %hash = ( perl => 'larry', ruby => 'matz',
); my $ref = \%hash; リファレンス > HashRef 51 # 略記 my $ref = { perl => 'larry', ruby => 'matz', };
リファレンス > HashRef 52 # % を頭につけてデリファレンス # keysは組み込み関数。ハッシュのキーの一覧を取得する my
@keys = keys %$ref; print $ref->{perl}; # -> で直接アクセス • リファレンスから値を取り出す
デリファレンスいろいろ 53 my $a_of_a = [ [1, 2, 3], [4,
5, 6],]; my @array = @{ $a_of_a->[1] }; • なにかの式をデリファレンスするときは @{ ... } とか %{ ... } で囲む
デリファレンスいろいろ 54 my $a_of_a = [ [1, 2, 3], [4,
5, 6]]; my @array = $a_of_a->[1]->@*; # => (4, 5, 6) • Postfix dereference
デリファレンスいろいろ 55 my $list = [1, 2, 3]; push @$list,
4; • 必要なときだけデリファレンスする
56 コンテキスト
コンテキスト • 代表的ハマりポイント • 式が評価される場所( = コンテキスト)によっ て結果が変わる 57
コンテキスト 58 my @array = (10, 20, 30); my @x
= @array; my $y = @array; my ($z) = @array; • それぞれ何が入っているでしょうか
コンテキスト 59 my @array = (10, 20, 30); my @x
= @array; # @array はリストコンテキストで評価される my $y = @array; # @array はスカラコンテキストで評価される my ($z) = @array; # @array はリストコンテキストで評価される • それぞれ何が入っているでしょうか
• $yには、配列をスカラコンテキストで評価す るので個数が返る コンテキスト 60 my @array = (10, 20,
30); my @x = @array; # @x = (10, 20, 30) my $y = @array; # $y = 3 my ($z) = @array; # $z = 10
• $zには、配列の先頭要素が代入され、残りは 捨てられている コンテキスト 61 my @array = (10, 20,
30); my @x = @array; # @x = (10, 20, 30) my $y = @array; # $y = 3 my ($z) = @array; # $z = 10
• ifの条件式はスカラコンテキスト • 要素があればtruthy、空配列は0になりfalsy コンテキストは便利 62 if (@$items) { ...
}
63 演算子、制御構造
演算子 64 • 普通の演算子はだいたいある ◦ defined-or (//) があるのは便利 • 文字列の比較は
== ではなく eq ◦ ==は数値比較用なので注意 ◦ 文字列比較にはeq, ne, gt, le等を用いる
制御構造 65 • if文とかは想像通りのものがだいたいある ◦ else if は無くelsif • forとforeachは同じキーワード
◦ for my $e (@$array) ◦ foreach my $e (@$array)
制御構造 66 • for my $e と受けないと$_が使われる ◦ for (@$array)
{ say $_ }; ◦ $_はここでは処理中の要素を表す特殊変数 • forのキーワードは珍しいか? ◦ continueではなくnext, breakではなくlast
Enumerable色々 67 my $items = [(3..7)]; for my $item (@$items)
{ ... } my $res = [ grep { $_ % 2 } @$items ]; # => # [3, 5, 7]
Enumerable色々 68 my $items = [(3..7)]; my $doubled = [
map { $_ * 2 } @$items ]; #=> [6, 8, 10, 12, 14] use List::Util qw(all); if (all { $_ > 0 } @$items) { say "すべて 0 より大きい" } # List::Util には min, uniq, sample, first 等だいたいある
例外 69 • ないことはない (eval期) • 便利モジュールでやる (Try::Tiny期) • そこにある
(try-catch期)
例外 70 # eval ブロックでエラーをトラップする # (これは典型的なよくないコードだけどevalブロックの説明のため) eval { ...;
}; if ($@) { # eval内で死ぬと特殊変数$@にエラーメッセージが入る ...; }
例外 71 use Try::Tiny; try { ...; } catch {
my $err = $_; # $_にエラーメッセージが入っている # die $err; # 再スロー };
例外 72 # feature try で圧倒的自然なコードに try { ...; }
catch ($e) { ...; }
73 サブルーチン
サブルーチン 74 # サブルーチン宣言 sub foo { my ($a, $b,
$c) = @_; } # サブルーチン呼び出し foo(1, 2, 3); # 引数なしで呼び出す場合はカッコを省略できる
サブルーチン > 引数 75 sub add { my ($x, $y)
= @_; return $x + $y; } my $three = add(1, 2); • 引数1,2は@_という特殊な配列に格納される ◦ これが($x, $y)に分割代入される
サブルーチン > 引数 76 sub add { my $x =
shift; my $y = $_[0]; # shift したので y が先頭要素 return $x + $y; } • shiftを使う ◦ 引数なしだと暗黙的に@_になり、先頭要素を取り出す • $_[0]で配列の最初を取り出すことも
サブルーチン > 引数 77 sub func1 { my ($arg1, $arg2,
%args) = @_; my $opt1 = $args{opt1}; my $opt2 = $args{opt2}; } func1('hoge', 'fuga', opt1 => 1, opt2 => 2); • よくやるイディオム ◦ 最後に%argsと受けると省略可能な名前付き引数に
サブルーチン > 引数(現代) 78 sub add($x, $y) { return $x
+ $y; } • Perl界にも仮引数があります! • 私はISUCON以外で見たことない
サブルーチン > はてなでは 79 use Smart::Args::TypeTiny qw(args); sub add {
args my $x => 'Int', my $y => 'Int'; return $x + $y; } • 実行時型チェックも同時に実現する Smart::Args::TypeTinyを使っている
サブルーチン > 値の返し方 80 • returnで返せるが、省略可能 • 省略した場合は最後に評価された式の返り値
サブルーチン > 値の返し方 81 sub swap_list($x, $y) { return ($y,
$x) } my ($x, $y) = swap_list('Hello','World'); #=> ($x: World', $y: 'Hello') • 多値を返して分割代入で受けられる ◦ スカラーで受け取ると個数になるから注意
サブルーチン > 引数 82 • 無名サブルーチンを引数で渡すのもよく見る ◦ 高階関数やブロックと同じ sub with_block
{ say "start"; $_[0]->(); # 渡された無名サブルーチンを実行 say "end"; } with_block(sub { say "in block" });
83 パッケージ
パッケージ 84 • 名前空間 • モジュールロードのしくみ • クラス(後述)
パッケージ > 名前空間 85 package Example::Greeter; • と書くと、それ以降のコードは Example::Greeter名前空間に属する •
パッケージとは関数等の名前が所属する先
パッケージ > 名前空間 86 package A; sub foo { ...
} package B; sub bar { ... } • それぞれA::foo、B::barで呼び出せる
パッケージ > モジュールロードの仕組 み 87 use My::File; # => My/File.pm
がロードされる • @INC(グローバル変数)に設定されたパスを検索 ◦ 慣習的に ./lib を@INCに含めている
パッケージ > モジュールロードの仕組 み 88 use My::File; # => My/File.pm
がロードされる • .pm=PerlModule。書き捨て以外は基本.pm • Carmel/Cartonで入れる他、コアモジュール (Perlインストール時に同梱)が数百ある ◦ $ corelist -v v5.34.1 で見てみよう
89 ここで休憩
90 オブジェクト指向
• オブジェクトとは ◦ プログラムの対象となるモノ ◦ データ + 手続き • クラスで実装されることが多い
◦ クラスには自身の持つデータに対する手続き(メソッ ド)が定義されている オブジェクト指向 91
オブジェクト指向 • Perlはもともとオブジェクト指向言語として 始まったわけではないので後付け ◦ ここが非常に面白い • パッケージとリファレンスだけで使える 92
オブジェクト指向 93 OOP用語 Perlでの用語 クラス パッケージ メソッド パッケージに定義された 関数 オブジェクト
パッケージにblessされた リファレンス
bless 94 # なんかデータがある(普通はハッシュリファレンス) my $data = { name =>
'motemen' }; # データにパッケージを紐付けると my $self = bless $data, 'Hatena::Engineer'; # メソッドが呼べる! ここでは Hatena::Engineer::tweet $self->tweet();
いいか、みんな (゚д゚ ) (| y |) ハッシュリファレンスと package では手続き型プログラミングしかできないが {}
( ゚д゚) package \/| y |\/ 二つ合わさればOOPとなる ( ゚д゚) bless (\/\/ オブジェクト指向 95
• コンストラクタも自分で書く ◦ newは慣習的な命名 オブジェクト指向 > コンストラクタ 96 package Person;
use v5.42; sub new { my ($class, %args) = @_; return bless \%args, $class; }
• Person->new(age => 18)は Person::new('Person', age => 18) オブジェクト指向 >
コンストラクタ 97 my $person = Person->new(age => 18); # { age => 18 } が Person に bless されたもの
• Klass->fooはKlass::foo('Klass')の糖衣構文 • $obj->fooはKlass::foo($obj)の糖衣構文 ◦ blessしているので$objからKlassに辿れる オブジェクト指向 98 package Klass;
sub class_method { my ($class, %args) = @_; ...; } package Klass; sub instance_method { my ($self, %args) = @_; ...; }
オブジェクト指向言語として使う 99 my $person = Person->new(name => 'motemen', age =>
18); # 元々 HashRef を bless しただけなので中身にアクセス可能 $person->{age} = 3; # だけど、当然 $person->age(3) でアクセスする package Person; sub age { $self = shift; $self->{age} = $_[0]; }
オブジェクト指向 後付けだが、データと手続きを繋げるblessの 導入と、ちょっとした糖衣構文だけで、手作 り感のあるオブジェクト指向だけど言語仕様 に非常に綺麗に収まっている 100
package Person; use Class::Accessor::Lite ( new => 1, rw =>
[ qw(name age) ], ); オブジェクト指向(ライブラリ) 101 • ものすごく書きやすくて便利だったが……
オブジェクト指向(現代) 102 use v5.42; use experimental 'class'; # まだ experimental
だが class Person { # class 記法が入った! field $name :param :reader; # 属性とアクセサ定義 method hello { say "Hi, I'm $name." } # メソッド定義 } my $onk = Person->new(name => 'onk'); $onk->hello;
103 スコープ
{ my $x = 10; say $x; # 10 }
say $x; # エラー(見えない) スコープ • 変数の見える範囲 ◦ myはレキシカルスコープ内に限定する宣言 ◦ スコープを絞るために任意にブロックを作れる 104
スコープ 105 • スコープ単位での変更を多用する文化 ◦ use strict; のようなプラグマもスコープ単位 • 参照カウント方式のメモリ管理の影響?
◦ スコープを抜けるときに破棄されるので
106 入出力
入出力 > 読み込み 107 open my $fh, '<', 'input.txt' or
die $!; while (my $line = <$fh>) { ...; } close $fh; • 有名なor die ◦ or の優先順位が低いおかげでカッコが要らない ◦ ( open my $fh, '<', $file ) or die $!
open my $fh, '<', 'input.txt' or die $!; local $/
= undef; # 入力区切り文字を変更 my $content = <$fh>; # ファイル全体を一度に読める close $fh; 入出力 > 読み込み 108 • いわゆるslurpパターン • 行指向言語なことを示していて慣れたら好き
my $content = do { # スコープを抜けたら自動 close open my
$fh, '<', 'input.txt' or die $!; local $/; # 代入しなくても undef になる <$fh>; }; 入出力 > 読み込み 109 • こういう書き方をしているところも多いかも ◦ do {} はブロックの結果を式として返す
open my $fh, '>', 'output.txt' or die $!; print $fh
"Hello\n"; close $fh; 入出力 > 書き込み 110 • printの第1引数にファイルハンドルを渡す ◦ デフォルトでSTDOUT ◦ 第1引数なのにカンマがないけどそういうものらしい
111 特殊変数
特殊変数 112 • 今まで説明してきたもの ◦ $_ : 色んなところで使う。mapやgrepの処理対象等 ◦ @_
: 引数 ◦ $@ : evalブロックの例外メッセージ ◦ $! : システムコール失敗時のエラーメッセージ ◦ $/ : 入力の区切り文字
特殊変数 113 • English module で別名が付いている ◦ $_ : $ARG
◦ @_ : @ARG ◦ $@ : $EVAL_ERROR ◦ $! : $ERRNO ◦ $/ : $INPUT_RECORD_SEPARATOR
114 UTF-8
use utf8; 115 • Perlでは文字列は以下のどちらか ◦ Perl の内部表現に変換された文字列 ◦ バイト列
print 'ほげ'; use utf8; 116 • UTF-8 でファイル(hoge.pl)に保存します • 実行します
$ perl hoge.pl ほげ • ええやん
print length 'ほげ'; use utf8; 117 • length は文字数をカウントする関数 •
実行します $ perl hoge.pl 6 • あかんやん
use utf8; 118 • 'ほげ' はマルチバイト文字 • 何もしないとPerlは'ほげ'をバイト列とみなす • UTF-8だと6バイトなのでlengthが6になる
• 文字数数えるのに (それ以外も色々) 困る
use utf8; print length 'ほげ'; use utf8; 119 • そこでuse
utf8; • 実行します $ perl hoge.pl 2 • ええやん!
use utf8; 120 • utf8 プラグマをつけると Perl はコード内の マルチバイト文字を UTF-8
の文字列として解 釈し、Perl 内部表現の文字列に変換する • UTF-8 で記述された "ほげ" を UTF-8 として 解釈すると length "ほげ" は 2 になる
use utf8; print 'ほげ'; use utf8; 121 • けど…… $
perl hoge.pl Wide character in say at hoge.pl line 2. ほげ • なんか出た
use utf8; 122 • Perl内部文字列になっている"ほげ"をそのま まPerlの世界の外に出そうとすると怒られる • 再びバイト列に変換してあげる必要がある
use utf8; use Encode qw(encode_utf8); print encode_utf8 'ほげ'; use utf8;
123 • これでOK
use utf8; 124 • utf8プラグマは文字列リテラルに効く ◦ 自動的に内部文字列になる • プログラムの外から渡された値は自分で内部 文字列に変換する
◦ decode_utf8; • 入口でdecode、出口でencodeの鉄則
use utf8; 125 • これはガチ • 「ããã¯ã¬ãããã¯ã¬ã」を見て気 づけるようになる
126 正規表現
正規表現 127 • Perlと言えば正規表現 ◦ 出自からしてテキスト処理に特化 ◦ Practical Extraction and
Report Language • 正規表現リテラルで、読み下しやすい if ($line =~ /ERROR/) { warn "error detected"; }
正規表現 128 • m// マッチ演算子 ◦ if ($str =~ m/foo/)
{ ... } # m は省略可 • s/// 置換演算子 ◦ $str =~ s/foo/bar/; ▪ $strを破壊的に変更する ◦ Perl v5.14 で非破壊操作が可能になった ▪ my $new = $str =~ s/foo/bar/r;
正規表現 129 while (<LOG>) { next unless /^ERROR\b/; # $_
=~ m/^ERROR\b/ と同じ s/^ERROR\s+//; # $_ を破壊的に書き換える print; # これも $_ 省略 } • 暗黙の$_を使うと急に読みづらくなるが、 慣れてるとサラッと書ける
正規表現 > PCRE 130 • Perl Compatible Regular Expressions •
CライブラリとしてPerl以外からでも使えるよ うに ◦ grep -PとかPHPとかに輸出されている
131 テスト
テスト 132 • テストを書くエコシステムが整っている ◦ prove というテスト実行用コマンドを同梱 • テストはt/ディレクトリ以下に置く ◦
拡張子は.t(中身はPerlスクリプト)
テスト 133 use Test2::V0; use Person; my $person = Person->new(age
=> 18); is $person->age, 18, '最初は18歳'; $person->incr_age; is $person->age, 19, 'incr_age 呼んだら19歳'; done_testing;
テスト 134 $ prove -lv t/Person.t .. # Seeded srand
with seed '20251114' from local date. ok 1 - 最初は18歳 ok 2 - incr_age 呼んだら19歳 1..2 ok All tests successful. Files=1, Tests=2, 0 wallclock secs ( 0.00 usr 0.00 sys + 0.02 cusr 0.00 csys = 0.02 CPU) Result: PASS
テスト 135 • テスト結果をTAP形式で表示 ◦ Test Anything Protocol ◦ TAPを読み取って加工するエコシステムがある
• テストはファイル単位 ◦ .t ファイルが独立している ◦ 分散テスト=テスト対象ファイルを分割するだけ
136 よくある罠5選
autovivification 137 my $config = {}; if ($config->{foo}->{bar} eq 'debug')
{ ...; } # autovivification によって $config->{foo} がHashRefに変化 # $config = { foo => { } }
文字列と数値の区別を付けづらい 138 • 文字列と数値の区別が非常に弱い • 文字列にしたらJSON出力も文字列になる ◦ { "id": "1"
} ◦ params も DB からの取得も基本は文字列…… • $val+0, $val.'' というテクニック ◦ 数値と計算すると数値に、文字列と結合すると文字列に ◦ JSON::Types という最高のライブラリ
localtimeでコンテキストを間違える 139 • localtime ◦ 現在時刻を取得できる関数 • スカラコンテキスト ◦ Fri
Nov 14 13:07:32 2025 • リストコンテキスト ◦ (32, 7, 13, 14, 10, '125', 5, 317, 0);
$_[0]に破壊的変更 140 • @_ を直接触ると、呼び出し元の値が変わる • 引数を一度 ($x) = @_;
等で引数に受けた後は $x に破壊的な変更をしても大丈夫
意図しないカンマ演算子 • my $a = ("a", "b", "c"); は $a
に "c" が入る • カンマ演算子は複数の式を左から順に評価し、 最後の式の値を返す演算子 ◦ my $x = (print "a", print "b", 100); ◦ ab を出力して $x == 100 になる ◦ 短絡評価のない && みたいな 141
142 まとめ
まとめ データ型 リファレンス コンテキスト 演算子 制御 構造 143 サブルーチン モジュール
オブジェクト指向 入出力 スコープ 特殊変数 UTF-8 正規表現 テスト 罠5選
まとめ • Perlの読み書きに必要なものと、知っている と面白い情報をまとめてお伝えした • これで今日からあなたもPerl Monger 144