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コーディングテクニック2018
Search
akiym
March 03, 2018
Programming
0
11k
Perlコーディングテクニック2018
YAPC::Okinawa 2018 ONNASON
akiym
March 03, 2018
Tweet
Share
More Decks by akiym
See All by akiym
Webセキュリティのあるきかた
akiym
40
16k
CPAN Module Hacks
akiym
0
2.4k
新時代のテストフレームワークTest2
akiym
2
19k
脆弱なアプリを書く技術
akiym
11
9.2k
Hokkaido.pm#11
akiym
0
5k
Herokuで学ぶ、初めてのPerl
akiym
5
2.8k
Perl meets Leap Motion
akiym
0
1.5k
github止まり モジュール5選
akiym
0
1.5k
Skype効率化
akiym
1
1.8k
Other Decks in Programming
See All in Programming
“あなた” の開発を支援する AI エージェント Bedrock Engineer / introducing-bedrock-engineer
gawa
11
1.9k
第3回関東Kaggler会_AtCoderはKaggleの役に立つ
chettub
3
1k
Open source software: how to live long and go far
gaelvaroquaux
0
630
[JAWS-UG横浜 #80] うわっ…今年のServerless アップデート、少なすぎ…?
maroon1st
1
180
動作確認やテストで漏れがちな観点3選
starfish719
6
1k
ペアーズでの、Langfuseを中心とした評価ドリブンなリリースサイクルのご紹介
fukubaka0825
2
320
GoとPHPのインターフェイスの違い
shimabox
2
180
XStateを用いた堅牢なReact Components設計~複雑なClient Stateをシンプルに~ @React Tokyo ミートアップ #2
kfurusho
1
890
Amazon Q Developer Proで効率化するAPI開発入門
seike460
PRO
0
110
DROBEの生成AI活用事例 with AWS
ippey
0
130
ISUCON14公式反省会LT: 社内ISUCONの話
astj
PRO
0
190
Grafana Cloudとソラカメ
devoc
0
170
Featured
See All Featured
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.4k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
114
50k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
29
1k
Designing for humans not robots
tammielis
250
25k
Building Adaptive Systems
keathley
40
2.4k
How STYLIGHT went responsive
nonsquared
98
5.4k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
21
2.5k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Reflections from 52 weeks, 52 projects
jeffersonlam
348
20k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
59k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
40
2k
The Language of Interfaces
destraynor
156
24k
Transcript
1FSM؝٦ر؍ؚٝ ذؙصحؙ BLJZN :"1$0LJOBXB0//"40/
BLJZN
1FSMחꟼְׅז鑧 ׃תׅ
剑鵚ך1FSM歲
剑鵚ֲֿ׃גְהְֲ鑧 耀ְֹ
剑鵚ךٌآُ٦ٕ סִַ
VTFTUSJDU
VTFTUSJDU VTFXBSOJOHT VTFVUG
VTFW VTFXBSOJOHT VTFVUG use strict; use feature ':5.26';
VTFTUSJDUVSFT use strict; use warnings FATAL => 'all'; use warnings
NONFATAL => qw( exec recursion internal malloc newline experimental deprecated portable ); no warnings 'once';
VTFTUSJDUVSFT use strict; use warnings FATAL => 'all'; use warnings
NONFATAL => qw( exec recursion internal malloc newline experimental deprecated portable ); no warnings 'once'; {a => 1, 2} Odd number of elements in anonymous hash
ؙٓأؽٕت
sub new { my ($class, %args) = @_; croak("required: z")
unless exists $args{z}; return bless \%args, $class; } sub z { $_[0]->{z} } CMFTT
Ⰻ鿇䩛דװ崢
use Moose; extends 'Point'; has 'z' => (isa => 'Int',
is => 'rw', required => 1); after 'clear' => sub { my $self = shift; $self->z(0); }; .PPTF.PVTF.PP
堣腉搀꼽ח⢪ֲֶה׃ג 醱꧟חזָ
use Class::Tiny qw(x y z); sub BUILD { my ($self,
$args) = @_; croak("required: z") unless exists $args->{z}; } $MBTT5JOZ
㼭ׁזך 穈さׇג⢪ֲ
use Class::Accessor::Lite ( ro => [qw/x y z/], ); sub
new { my ($class, %args) = @_; croak("required: z") unless exists $args{z}; return bless \%args, $class; } CMFTT $MBTT"DDFTTPS-JUF
鵚➿涸 FYQPSU遭
use Exporter 'import'; our @EXPORT = qw/foo bar baz/; Foo.pm
test.pl use Foo; foo();
倜׃ְꟼ侧ך鷄⸇䖓ח !&91035ח鷄⸇ׅך 䘌ָ
.PEVMF'VODUJPOT use Module::Functions qw/get_public_functions/; use Exporter 'import'; our @EXPORT =
get_public_functions; use JSON qw/decode_json/; sub bar { ... } sub _foo { ... } 㢩鿇ַFYQPSU׃ꟼ侧כ搀鋔 @ַ㨣תꟼ侧כ搀鋔
*NQPSUFS use Importer Importer => 'import'; use Importer 'List::Util' =>
( any => {-as => 'list_util_any'}, ); VTF&YQPSUFSJNQPSUךַ ⴽせדJNQPSUדֹ
ٌآُ٦ٕ ٗ٦ت٦
⹛涸חٌآُ٦ٕ铣鴥 ❌ eval qq{require "Plugin/$name.pm"}
6/*7&34"-SFRVJSF 'Foo::Bar'->require;דֹ ְְַֽֿ*/$״ٗ٦س幥ַⴻ㹀
.PEVMF-PBE ؝،ٌآُ٦ٕ ءٝفٕ׃暴ח⢪ג㉏겗זְ
$MBTT-PBE USZ@MPBE@DMBTT ׅדחٗ٦س幥ַⴻ倖ׅJT@DMBTT@MPBEFE
.PEVMF3VOUJNF $MBTT-PBEⰻ鿇ד⢪גְ ٌآُ٦ٕٗ٦ت٦ך㹀殢
require_module($name); use_package_optimistically($name); compose_module_name('Foo', $name); ٌآُ٦ٕⰻדؒٓ٦ָ涪欰׃הֹֽ⢽㢩䫎־ 湫䱸KPJO 'PP OBNF ׃זְ
֮ط٦يأل٦أ⟃♴ך ٌآُ٦ٕׅץגٗ٦سׅ
use Module::Find qw/useall/; useall('Foo::Handler'); .PEVMF'JOE 'PP)BOEMFS⟃♴ח֮ 'PP)BOEMFS"װ'PP)BOEMFS"#ٗ٦س
5ZQF5JOZ ⢪ג㘗⢪ֲ
؝٦سָ竰ֺ駈ׁגְ ذأزךقٕػ
sub create_xxx { my (%args) = @_; if ($args{foo}) {
... } db->insert( x => 100, y => 'abc', %args, ); } ְזךָ床ׇ 剑穄涸חכ湫䱸床׃ג׃תֲ ㄎן⳿׃⩎חׅץג㨻י
UZQPח䓲ְ ⢪ְ倯ָⴓַזְךד ְְ鋅חְֻ
床גֹ䒷侧 ثؑحؙׅ
ֿזהֹחכغٔر٦ة 䗳갭ػًٓ٦ةָ床ׁגְַ 㘗ثؑحؙ
use Params::Validate qw(:all); sub foo { my %args = validate(@_,
{ foo => { type => ARRAYREF }, bar => { isa => 'Bar' }, }); } 1BSBNT7BMJEBUF
use Data::Validator; sub foo { state $rule = Data::Validator->new( foo
=> { isa => 'ArrayRef' }, bar => { isa => 'Bar' }, ); my $args = $rule->validate(@_); } %BUB7BMJEBUPS .PVTFך㘗 غٔر٦ةך㹀纏ךٍؗحءָُ〳腉 「ֽ《ػًٓ٦ةכIBTISFGד乼⡲
use Smart::Args; sub foo { args my $foo => 'ArrayRef',
my $bar => 'Bar', ; } 4NBSU"SHT !@床ׅ䗳銲ָזְ غٔر٦ةך㹀纏ٍؗحءُדֹזְ 「ֽ《ػًٓ٦ةכ㢌侧ד乼⡲
None
!@床ׁ׆חㄎן⳿׃⯋ך!@《 1BE8BMLFS⢪ְծ床׃㢌侧せ《⳿ׅ
use Mouse::Util::TypeConstraints; my $type = find_or_create_isa_type_constraint('Int'); $type->check($x); ⰻ鿇דכ.PVTFך㘗䪔ֲ
5ZQF5JOZ
Any Item Bool Maybe[`a] Undef Defined Value Str Num Int
ClassName RoleName Ref ScalarRef ArrayRef[`a] HashRef[`a] CodeRef RegexpRef GlobRef FileHandle Object ArrayRef[User] Maybe[Str] .PPTF✼䳔
Map[`k, `v] Tuple[...] Dict[...] Optional[`a] InstanceOf[`a] ConsumerOf[`a] HasMethods[`a] Overload[`a] Tied[`a]
StrMatch[`a] Enum[`a] OptList LaxNum StrictNum CycleTuple[`a] MkOpt Split[`a] Join[`a] Dict[a => Int, b => Str] Enum['public', 'private'] .PPTF95ZQFT4USVDUVSFE✼䳔
.PVTFה5ZQF5JOZך麩ְ
use Mouse::Util::TypeConstraints; subtype 'NonEmptyStr', as 'Str', where { length($_) >
0 }; my $type = find_type_constraint('NonEmptyStr'); $type->check('str'); .PVTF ؚٗ٦غٕז㘗㹑鎉
use Type::Standard -types; use Type::Utils -all; subtype 'NonEmptyStr', as Str,
where { length($_) > 0 }; NonEmptyStr->check('str'); 5ZQF5JOZ ך㜥ד㘗ךؔـآؙؑز⡲䧭 㢩鿇ַ⢪ֲ㜥さכFYQPSUׇׁ
4NBSU"SHT5ZQF5JOZ 4NBSU"SHTד5ZQF5JOZך㘗 䪔ִ״ֲח׃ך 4NBSU"SHTה㢌׆⢪ִ
use Types::Standard -types; sub foo { args my $x =>
{isa => 'Int', default => 100}, my $y => {isa => Str, default => 'abc'}, my $bar => 'Bar', my $bar => 'NonEmptyStr', ; } 5ZQF5JOZך㘗⢪ִ 俑㶵ה׃ג床ׇ .PVTF6UJM5ZQF$POTUSBJOUTד㹑鎉׃㘗⢪ִ
use Types::Standard qw/Str/; use Params::ValidationCompiler; sub foo { state $validator
= validation_for( params => { foo => { type => Str }, }, ); my %args = $validator->(@_); } 1BSBNT7BMJEBUJPO$PNQJMFS
倜׃ְ1FSMך 堣腉⢪ֲ
QPTUYEFSFGFSFODF QFSM⟃꣬ד姻䒭堣腉⻉
$$a $a->$* @$a $a->@* $#$a $a->$#* %$a $a->%* &$a $a->&*
*$a $a->**
$$a $a->$* @$a $a->@* $#$a $a->$#* %$a $a->%* &$a $a->&*
*$a $a->**
my $x = {a => [1, 2, 3], b =>
[4]}; 兛鸐ךEFSFGFSFODF @{$x->{a}} $x->{a}->@* QPTUYEFSFGFSFODF
map { $_->id } @{ Foo->bar( ... ) }; map
{ $_->id } Foo->bar( ... )->@*; 兛鸐ךEFSFGFSFODF QPTUYEFSFGFSFODF
use constant A => [1, 2, 3]; !"דכזְ" ד ㄎן⳿׃גֶֻ䗳銲ָ֮
兛鸐ךEFSFGFSFODF @{A()} A->@* QPTUYEFSFGFSFODF @{+A}
QFSM ⟃ד⢪ְְ
QPTUYEFSFGFSFODF㢌䳔 IUUQTHJUIVCDPNBLJZNMFHBDZ@QPTUYEFSFG
11*⢪ג WBS! !WBSח 剅ֹ䳔ִ
➙ּׅQPTUYEFSFGFSFODF ⢪ִ
ֶ
5.5085%* 5IFSFT.PSF5IBO0OF8BZ5P%P*U