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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
20k
CPAN Module Hacks
akiym
0
2.7k
新時代のテストフレームワークTest2
akiym
2
19k
脆弱なアプリを書く技術
akiym
11
9.4k
Hokkaido.pm#11
akiym
0
5.1k
Herokuで学ぶ、初めてのPerl
akiym
5
2.9k
Perl meets Leap Motion
akiym
0
1.6k
github止まり モジュール5選
akiym
0
1.6k
Skype効率化
akiym
1
2k
Other Decks in Programming
See All in Programming
How to stabilize UI tests using XCTest
akkeylab
0
130
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
470
encoding/json/v2のUnmarshalはこう変わった:内部実装で見る設計改善
kurakura0916
0
410
AIに任せる範囲を安全に広げるためにやっていること
fukucheee
0
130
CSC307 Lecture 15
javiergs
PRO
0
250
20260313 - Grafana & Friends Taipei #1 - Kubernetes v1.36 的開發雜記:那些困在 Alpha 加護病房太久的 Metrics
tico88612
0
200
AI Assistants for Your Angular Solutions
manfredsteyer
PRO
0
140
モダンOBSプラグイン開発
umireon
0
130
Unity6.3 AudioUpdate
cova8bitdots
0
130
AI 開発合宿を通して得た学び
niftycorp
PRO
0
120
「やめとこ」がなくなった — 1月にZennを始めて22本書いた AI共創開発のリアル
atani14
0
390
Windows on Ryzen and I
seosoft
0
290
Featured
See All Featured
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
0
160
Agile that works and the tools we love
rasmusluckow
331
21k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.2k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.9k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
110
How to make the Groovebox
asonas
2
2k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
Testing 201, or: Great Expectations
jmmastey
46
8.1k
Bash Introduction
62gerente
615
210k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Designing Experiences People Love
moore
143
24k
Code Review Best Practice
trishagee
74
20k
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