Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Perlにおける動的なモジュールロードのメリットとデメリット
Search
ybrliiu
November 03, 2019
Technology
940
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Perlにおける動的なモジュールロードのメリットとデメリット
ybrliiu
November 03, 2019
More Decks by ybrliiu
See All by ybrliiu
これまでと、これからのPerlコミュニティ
ybrliiu
0
180
AstroNvim を使おう!
ybrliiu
0
5.6k
Perlでも関数の型をチェックしたい
ybrliiu
0
3.9k
Perl5.32の新機能
ybrliiu
0
200
Vue.jsで作ったサイトをバニラJSで書き直す悲しいお話
ybrliiu
1
1.2k
黒魔術で独自定義のenum型制約を満たす値のリ ストを取得する話
ybrliiu
0
470
Perlにおけるクラスの実装パターン.pdf
ybrliiu
0
1.8k
Presentation.pdf
ybrliiu
0
310
ぼくがPerlで開発を行う時に工夫していること
ybrliiu
0
590
Other Decks in Technology
See All in Technology
SAENM ~Jupyterで残すPoCの試行錯誤、未来の自分と仲間を助ける記録!~
terapyon
0
120
Local CI × GitHub Actions
gogutan
3
230
AI導入は済んだ。次は統制を作り替える番だ_AI×開発組織 Summit 2026
techtekt
PRO
0
360
Optunaの最新リリースv5.0について
pfn
PRO
0
120
実体験から学ぶ分析エージェントの開発と運⽤
recruitengineers
PRO
8
2.4k
実践! SRE × AI - ABEMA における AIOps -
tetsuya28
8
3.1k
Rustuna: Rustによる高速なOptuna実装
pfn
PRO
0
200
AI駆動で「他アプリの音を加工できる」アプリを作った
satomasahiro2005
0
170
WasmをRustにする
sansantech
PRO
0
280
Temporal 最高!でも改めて「日付」について調べたら人類の負債すぎる件
riyaamemiya
0
180
Persisting Massive Data with Rails ~Designing for 60 billion rows, and fighting the bottlenecks~ Railsで挑む大量データ永続化 〜600億件を永続化するための設計とボトルネックとの戦い〜
occhi
0
740
初海外で注意すべきこと12選!!!安全快適なre:invent生活にするために
yuuuuuuu168
1
180
Featured
See All Featured
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.7k
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
550
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
1
280
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
590
Into the Great Unknown - MozCon
thekraken
41
2.8k
Why Our Code Smells
bkeepers
PRO
340
58k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
460
Designing for Performance
lara
612
70k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.9k
sira's awesome portfolio website redesign presentation
elsirapls
0
460
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
500
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句の中で頑張って静的にロードさせるようにすることができる • 依存関係が循環しているような場合は結合度が高く、設計としてよく ない状態になっているので設計を修正する
まとめ
まとめ • 動的なモジュールロードは下手な使い方をすると保守性が下がってし まう ◦ 静的なモジュールロードを行う方法でできないか検討しよう ◦ 動的なモジュールロードをする方が合理的なら保守性が下がらな いように工夫しよう
ご清聴ありがとうございました