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
ybrliiu
November 03, 2019
Technology
0
900
Perlにおける動的なモジュールロードのメリットとデメリット
ybrliiu
November 03, 2019
Tweet
Share
More Decks by ybrliiu
See All by ybrliiu
これまでと、これからのPerlコミュニティ
ybrliiu
0
180
AstroNvim を使おう!
ybrliiu
0
5.2k
Perlでも関数の型をチェックしたい
ybrliiu
0
3.6k
Perl5.32の新機能
ybrliiu
0
190
Vue.jsで作ったサイトをバニラJSで書き直す悲しいお話
ybrliiu
1
1.2k
黒魔術で独自定義のenum型制約を満たす値のリ ストを取得する話
ybrliiu
0
440
Perlにおけるクラスの実装パターン.pdf
ybrliiu
0
1.7k
Presentation.pdf
ybrliiu
0
290
ぼくがPerlで開発を行う時に工夫していること
ybrliiu
0
570
Other Decks in Technology
See All in Technology
Oracle Cloud Infrastructure(OCI):Onboarding Session(はじめてのOCI/Oracle Supportご利⽤ガイド)
oracle4engineer
PRO
2
17k
GitHub Copilot CLI で Azure Portal to Bicep
tsubakimoto_s
0
290
FASTでAIエージェントを作りまくろう!
yukiogawa
4
160
DMBOKを使ってレバレジーズのデータマネジメントを評価した
leveragestech
0
460
JAWS DAYS 2026でAIの「もやっと」感が解消された話
smt7174
1
110
サイボウズ 開発本部採用ピッチ / Cybozu Engineer Recruit
cybozuinsideout
PRO
10
76k
FastMCP OAuth Proxy with Cognito
hironobuiga
3
220
会社紹介資料 / Sansan Company Profile
sansan33
PRO
16
410k
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
11k
「お金で解決」が全てではない!大規模WebアプリのCI高速化 #phperkaigi
stefafafan
5
2.4k
AgentCoreとLINEを使った飲食店おすすめアプリを作ってみた
yakumo
2
260
Kiro Meetup #7 Kiro アップデート (2025/12/15〜2026/3/20)
katzueno
2
270
Featured
See All Featured
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.8k
It's Worth the Effort
3n
188
29k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
52k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
How STYLIGHT went responsive
nonsquared
100
6k
Ethics towards AI in product and experience design
skipperchong
2
240
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
160
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
160
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
0
250
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
64
53k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
440
Transcript
Perlにおける動的なモジュールロードの メリットとデメリット YAPC::Nagoya::Tiny @_ybrliiu
自己紹介 • id: mp0liiu / @_ybrliiu • 所属 : 株式会社モバイルファクトリー
• 新卒2年目(23歳) • Perl歴約7年 • 最近はソフトウェアアーキテクチャとか型に関心があります ◦ https://github.com/ybrliiu/p5-Types-TypedCodeRef
Perlの好きなところ • TMTOWTDI • 特にオブジェクト指向の実現方法がいろいろあるところ ◦ Any reference base class,
Inside-out class, いろんなクラスビ ルダー, etc... • 最近Perlコアにオブジェクト指向の構文を入れようという提案がでて いたりしていてテンションが上っています
よろしくお願いいたします!!!
なぜこの発表をしようと思ったのか • これまで趣味 + お仕事で動的なモジュールロードを行うコードをカ ジュアルに書いてきました • そのようなコードを運用していると、後から辛くなってくることが多かっ たので、なぜそうなっているのかを整理し、どうすれば改善できるのか を考えました
• http://mp0liiu.hatenablog.com/entry/2019/02/28/111424
次のようなコードがありました • とあるソーシャルゲームのコード • アイテムを使用すると、アイテムの種類に応じて効果が発動する • アイテムのデータはDBで管理されている
エンジニアA 「いちいちアイテム効果クラスを1つ1つuseしてアイテム の種類と対応させるコードを書くのめんどくさいなー」 エンジニアA 「せや!アイテムデータの種類を見て正規表現でいい感 じのアイテムクラス名を作ってそれをロードするようにするんや!」 エンジニアA 「よし!簡潔に書けていいな!」
数カ月後・・・
新しい効果をもつアイテムを追加することになりました
エンジニアB 「新しいアイテムのデータも追加したしアイテムの効果も 実装するか」 エンジニアB 「とりあえず他のアイテムのクラスを真似て作ろう」 エンジニアB 「クラス名はなんてすればいいんだ? grepしてもアイテム 効果クラスが使われている場所が見つからないぞ?」
None
今回の発表で伝えたいこと • 動的なモジュールロードは柔軟性がありすぎるので下手な使い方をす ると保守性が下がってしまう ◦ 静的なモジュールロードを行う方法でできないか検討しよう ◦ 動的なモジュールロードをする方が合理的なら保守性が下がらな いように工夫しよう
今日話すこと • 静的なモジュールロードと動的なモジュールロードについて • 動的なモジュールロードのメリット • 動的なモジュールロードのデメリット • 保守性を下げないようにするには
静的なモジュールロード • コンパイルフェーズで行うモジュールロードのこと • 通常は use でロード • ロードするタイミングやロードするモジュールに制約がかかる ◦
少なくともランタイムが開始する前にどんなモジュールがロードさ れるかが定まるようになっていないけない
動的なモジュールロード • ランタイムで行うモジュールロードのこと • ロードするタイミングやモジュールを好きなように決められる • 言語組み込みの機能で行うのなら require でのモジュールロード ◦
ロードするモジュールを動的に決めたいなら eval “require ...” • 通常は Module::Load, Class::Load などといったモジュールローダー を利用してロード
動的なモジュールロード • use する場合と挙動が違うところがあるので注意 ◦ import は自動的に呼ばれない ◦ CHECK, INITブロックに書かれたコードが実行されない
動的なモジュールロードを行うことによる メリット あるいはどのようなときに動的なモジュールロードを行いたくなるのか
コード量が少なくなる
for, while 文などでまとめてロードすればコード量が減る
Module::Find を利用すると、ある名前空間の下に属するモジュール をすべて読み込むことができる
Catalyst 風のモジュールローダーを利用する • useしなくてもモジュールを使える、use忘れがなくなる • パッケージ名を短く書ける
プラガブルなモジュールを簡単に作れる
モジュールに新たなメソッドを追加したりやモンキーパッチを当てれる ようにしたい場合 (Tengのようなケース)
None
与えられたものを読み取って何かするようなモジュールに、ルールを 追加していける構造にしたい (Perl::Critic のようなケース)
None
動的にディスパッチできる • 利用するモジュールを動的にディスパッチできる • プログラムの外部で管理されていたり、外部から受け付ける入力に応 じて処理を分岐させたい場合に非常に便利 ◦ 項目が多いマスタデータの種類に応じて ◦ HTTPリクエストの内容に応じて
動的にディスパッチできる
起動 / ロードにかかる時間の短縮 • モジュールをロードするタイミングをモジュール内のコードを実行する 直前にまで遅らせることで、アプリケーションの起動やモジュールの ロードにかかる時間を短くすることができる ◦ 当然その分実行時に短くした分の時間がかかる •
高速化を意識しているCPANモジュールや巨大なアプリケーションで よく見かける ◦ Moo, Type::Tiny, Class::Accessor::Lite, etc...
依存関係を動的に解決できる • 依存関係を動的に解決できる ◦ 条件に応じて依存モジュールを変更できる ◦ モジュールが相互に依存しても警告が発生しない • モジュールロードに失敗した場合の処理が書ける
動的なモジュールロードを行うことによる デメリット 開発体験にどのような悪影響がでるのか
可読性が下がる • 動的にロードするモジュール名を組み立てていると発生する問題 • 特に動的にモジュールロードされていることを知らない人がコードを 読むと、どこで何のモジュールが使われているのかがわかりにくい ◦ 特に正規表現でモジュール名を作ったりしていると非常に厳しい
可読性が下がる • 本質的には greppability の話 ◦ 調べたいコードが検索しにくい状態になってしまう ◦ 動的にシンボルを組み立てているとコードが検索しにくくて機械 も人間も辛い思いをする
◦ 静的解析を利用したツールの恩恵を授かれない恐れも
良くない設計の原因になる • どこでモジュールがロードがされるかわかりにくくなるので、注意しな いと混沌とした依存関係や構造ができあがる • モジュールの先頭で依存しているモジュールがまとめて use されて いる方が依存関係はわかりやすい •
依存関係が循環しているモジュールがあっても警告がでない
実際にロードされるまで動くかわからない • 依存しているモジュールがエラーなどで動かなくなっていても、実際 にコードが動くまでわからない • しっかりテストが書かれていたり、 Test::UseAllModules::all_use_ok みたいなテストが用意されてい るならそんなに問題にはならない •
またリッチな機能をもつエディタなら Syntax Error とかにも気づきや すい
つまり、むやみに動的なモジュールロード を行うと保守性が下がる
静的にモジュールロードする場合、柔軟性がない分 保守性が下がるような書き方をしにくい
なるべく静的にモジュールロードしたい
動的なモジュールロードを行うほうが合理的なときは、 なるべく保守性が下がらないようにしたい
どうするか
コード量を減らしたいとき
パッケージ名が長すぎる モジュールローダーの代わりに 定数や aliased でパッケージ名のエイリ アスを作る
use 忘れを防ぎたい • 現状代替案は知りません・・・ • いい方法を知っている方がいれば教えて下さい! • 理想を言えば他の言語みたいにエディタやIDEの機能でパッケージを 利用していたら自動でuseできるようになってほしい •
うたがわさんが便利そうなプラグインを作られていました ◦ 開発体験良くなりそうですね
まとめてロードしたい • 普通にuseする方法では不可能 • そもそもたくさんのモジュールをロードしたいケースは頻繁にあるの か? ◦ 拡張性を重視する構造でなければ、責務が大きくなりすぎている 可能性がある ◦
その場合はモジュールを分割すべき
まとめてロードしたい • 拡張性を重視していたり、useを延々と書き続けるのが現実的ではな い場合は動的にロードすべき • ただし保守性が低下しないように工夫する ◦ まとめすぎない (Module::Find::useall()) ◦
動的にパッケージ名を組み立てない ◦ Test::UseAllModules などを利用してコンパイルフェーズでエ ラーが起きないかをテストするようにする
プラグイン機構を実装したい時 • 手間がかかるが、プラグインオブジェクトを外でuseして作って渡すこ ともできる • フレームワークだったりプラガブルにしたい場合は動的にロードする のもよい • プロダクトのコード、特にビジネスロジックなどではプラガブルな構造 を用意するのはやり過ぎなケースが多い
◦ 基本的に保守性を重視して静的にロードする
モジュールに新たなメソッドを追加したりやモンキーパッチを当てれ るようにしたい場合 (Tengのようなケース)
None
動的にディスパッチしたい時 • 利用しうるモジュールは全て事前にロードしておき、外部からの値に 応じて利用するモジュールを分けるような対応表を書くことで対応で きる ◦ 数が多いなら対応表を自動生成する仕組みをつくるという手も • 工数、拡張性と保守性のトレードオフになるので状況に応じて判断 •
利用するパッケージ名を難しい正規表現とかで作っている場合は読 みにくくなるので対応表をちゃんと書くべき
動的にディスパッチしたい時
起動 / ロードにかかる時間の短縮 • 起動やロードにかかる時間を短縮したい場合は動的にロードするし かない • 保守性との引き換えになることを念頭に置いた上で、なるべく保守性 がおちないように工夫する ◦
良くない設計になってしまわないように注意を払う ◦ 動的にパッケージ名を組み立てない ◦ Test::UseAllModules などを利用してテストする
依存関係を動的に解決したい • 条件が実行する前に決まるなら if プラグマを利用したり、importや BEGIN句の中で頑張って静的にロードさせるようにすることができる • 依存関係が循環しているような場合は結合度が高く、設計としてよく ない状態になっているので設計を修正する
まとめ
まとめ • 動的なモジュールロードは下手な使い方をすると保守性が下がってし まう ◦ 静的なモジュールロードを行う方法でできないか検討しよう ◦ 動的なモジュールロードをする方が合理的なら保守性が下がらな いように工夫しよう
ご清聴ありがとうございました