Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Perlブートキャンプ
Search
Hatena
November 14, 2025
Technology
0
2.5k
Perlブートキャンプ
2025-11-14 YAPC::Fukuoka 2025
Hatena
November 14, 2025
Tweet
Share
More Decks by Hatena
See All by Hatena
エンジニアリング マネージャーの育成と評価軸の考え方
hatena
0
240
はてなサマーインターンシップ2025 Web API 講義資料
hatena
0
680
はてなサマーインターンシップ2025 フロントエンド 講義資料
hatena
19
9.1k
はてなサマーインターンシップ2025 コンテナ + Kubernetesハンズオン 講義資料
hatena
0
410
はてなサマーインターンシップ2025 クラウドと運用 講義資料
hatena
0
410
はてなサマーインターンシップ2025 RDBMSの基礎 講義資料
hatena
0
450
はてなサマーインターンシップ2025 セキュリティ 講義資料
hatena
0
450
はてなサマーインターンシップ2025 AIエージェント活用 講義資料
hatena
1
2.1k
はてなサマーインターンシップ2025 プロダクトマネジメント 講義資料
hatena
0
480
Other Decks in Technology
See All in Technology
useEffectってなんで非推奨みたいなこと言われてるの?
maguroalternative
10
6.4k
Ruby で作る大規模イベントネットワーク構築・運用支援システム TTDB
taketo1113
1
110
Databricksによるエージェント構築
taka_aki
1
140
Oracle Database@Google Cloud:サービス概要のご紹介
oracle4engineer
PRO
0
670
[JAWS-UG 横浜支部 #91]DevOps Agent vs CloudWatch Investigations -比較と実践-
sh_fk2
1
220
グレートファイアウォールを自宅に建てよう
ctes091x
0
130
eBPFとwaruiBPF
sat
PRO
4
2.4k
Agentic AI Patterns and Anti-Patterns
glaforge
1
160
オープンデータの内製化から分かったGISデータを巡る行政の課題
naokim84
2
1.4k
生成AIでテスト設計はどこまでできる? 「テスト粒度」を操るテーラリング術
shota_kusaba
0
290
事業部のプロジェクト進行と開発チームの改善の “時間軸" のすり合わせ
konifar
9
3.2k
Playwright x GitHub Actionsで実現する「レビューしやすい」E2Eテストレポート
kinosuke01
0
190
Featured
See All Featured
GraphQLとの向き合い方2022年版
quramy
50
14k
Optimising Largest Contentful Paint
csswizardry
37
3.5k
Reflections from 52 weeks, 52 projects
jeffersonlam
355
21k
It's Worth the Effort
3n
187
29k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.2k
How to Ace a Technical Interview
jacobian
280
24k
Building Flexible Design Systems
yeseniaperezcruz
329
39k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
24k
4 Signs Your Business is Dying
shpigford
186
22k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.1k
Mobile First: as difficult as doing things right
swwweet
225
10k
RailsConf 2023
tenderlove
30
1.3k
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