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
37
14k
CPAN Module Hacks
akiym
0
2.4k
新時代のテストフレームワークTest2
akiym
2
19k
脆弱なアプリを書く技術
akiym
11
9.1k
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.7k
Other Decks in Programming
See All in Programming
What’s New in Compose Multiplatform - A Live Tour (droidcon London 2024)
zsmb
1
470
詳細解説! ArrayListの仕組みと実装
yujisoftware
0
580
色々なIaCツールを実際に触って比較してみる
iriikeita
0
330
Streams APIとTCPフロー制御 / Web Streams API and TCP flow control
tasshi
2
350
シールドクラスをはじめよう / Getting Started with Sealed Classes
mackey0225
4
640
Outline View in SwiftUI
1024jp
1
320
ペアーズにおけるAmazon Bedrockを⽤いた障害対応⽀援 ⽣成AIツールの導⼊事例 @ 20241115配信AWSウェビナー登壇
fukubaka0825
6
1.8k
Realtime API 入門
riofujimon
0
150
距離関数を極める! / SESSIONS 2024
gam0022
0
280
3rd party scriptでもReactを使いたい! Preact + Reactのハイブリッド開発
righttouch
PRO
1
600
どうして僕の作ったクラスが手続き型と言われなきゃいけないんですか
akikogoto
1
120
Why Jakarta EE Matters to Spring - and Vice Versa
ivargrimstad
0
1k
Featured
See All Featured
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
16
2.1k
Building Applications with DynamoDB
mza
90
6.1k
Building an army of robots
kneath
302
43k
The Art of Programming - Codeland 2020
erikaheidi
52
13k
Code Review Best Practice
trishagee
64
17k
Large-scale JavaScript Application Architecture
addyosmani
510
110k
Become a Pro
speakerdeck
PRO
25
5k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Testing 201, or: Great Expectations
jmmastey
38
7.1k
Git: the NoSQL Database
bkeepers
PRO
427
64k
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