Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Perlコーディングテクニック2018

akiym
March 03, 2018

 Perlコーディングテクニック2018

YAPC::Okinawa 2018 ONNASON

akiym

March 03, 2018
Tweet

More Decks by akiym

Other Decks in Programming

Transcript

  1. 1FSM؝٦ر؍ؚٝ

    ذؙصحؙ
    BLJZN
    :"1$0LJOBXB0//"40/

    View Slide

  2. BLJZN

    View Slide

  3. 1FSMחꟼׅ׷ְ׹׿ז鑧׾
    ׃תׅ

    View Slide

  4. 剑鵚ך1FSM歲꥔

    View Slide

  5. 剑鵚ֲֿ׃גְ׷הְֲ鑧׾
    耀ֹ׋ְ

    View Slide

  6. 剑鵚ךٌآُ٦ٕ׾
    ס׶ִַ׷

    View Slide

  7. VTFTUSJDU

    View Slide

  8. VTFTUSJDU
    VTFXBSOJOHT
    VTFVUG

    View Slide

  9. VTFW
    VTFXBSOJOHT
    VTFVUG
    use strict;
    use feature ':5.26';

    View Slide

  10. VTFTUSJDUVSFT
    use strict;
    use warnings FATAL => 'all';
    use warnings NONFATAL => qw(
    exec
    recursion
    internal
    malloc
    newline
    experimental
    deprecated
    portable
    );
    no warnings 'once';

    View Slide

  11. 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

    View Slide

  12. ؙٓأؽٕت

    View Slide

  13. sub new {
    my ($class, %args) = @_;
    croak("required: z") unless exists $args{z};
    return bless \%args, $class;
    }
    sub z { $_[0]->{z} }
    CMFTT

    View Slide

  14. Ⰻ鿇䩛דװ׷崢

    View Slide

  15. use Moose;
    extends 'Point';
    has 'z' => (isa => 'Int', is => 'rw', required => 1);
    after 'clear' => sub {
    my $self = shift;
    $self->z(0);
    };
    .PPTF.PVTF.PP

    View Slide

  16. 堣腉搀꼽ח⢪ֲֶה׃ג
    醱꧟חז׶ָ׍

    View Slide

  17. use Class::Tiny qw(x y z);
    sub BUILD {
    my ($self, $args) = @_;
    croak("required: z") unless exists $args->{z};
    }
    $MBTT5JOZ

    View Slide

  18. 㼭ׁז׮ך׾
    穈׫さ׻ׇג⢪ֲ

    View Slide

  19. 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

    View Slide

  20. 鵚➿涸
    FYQPSU遭

    View Slide

  21. use Exporter 'import';
    our @EXPORT = qw/foo bar baz/;
    Foo.pm
    test.pl
    use Foo;
    foo();

    View Slide

  22. 倜׃ְꟼ侧ך鷄⸇䖓ח
    !&91035ח׮鷄⸇ׅ׷ך׾
    䘌׸ָ׍

    View Slide

  23. .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׃׋ꟼ侧כ搀鋔
    @ַ׵㨣ת׷ꟼ侧כ搀鋔

    View Slide

  24. *NQPSUFS
    use Importer Importer => 'import';
    use Importer 'List::Util' => (
    any => {-as => 'list_util_any'},
    );
    VTF&YQPSUFSJNQPSUךַ׻׶
    ⴽせדJNQPSUדֹ׷

    View Slide

  25. ٌآُ٦ٕ
    ٗ٦ت٦

    View Slide

  26. ⹛涸חٌآُ٦ٕ׾铣׫鴥׬
    ❌ eval qq{require "Plugin/$name.pm"}

    View Slide

  27. 6/*7&34"-SFRVJSF
    'Foo::Bar'->require;דֹ׷
    ַ׏ְְֿ׌ֽ*/$״׶ٗ٦س幥׫ַⴻ㹀

    View Slide

  28. .PEVMF-PBE
    ؝،ٌآُ٦ٕ
    ءٝفٕ׌׃暴ח⢪׏ג㉏겗זְ

    View Slide

  29. $MBTT-PBE
    [email protected]@DMBTT
    ׅדחٗ٦س幥׫ַⴻ倖ׅ׷[email protected]@MPBEFE

    View Slide

  30. .PEVMF3VOUJNF
    $MBTT-PBE׮ⰻ鿇ד⢪׏גְ׷
    ٌآُ٦ٕٗ٦ت٦ך㹀殢

    View Slide

  31. require_module($name);
    use_package_optimistically($name);
    compose_module_name('Foo', $name);
    ٌآُ٦ٕⰻדؒٓ٦ָ涪欰׃׋הֹ׌ֽ⢽㢩׾䫎־׷
    湫䱸KPJO 'PP OBNF
    ׃זְ

    View Slide

  32. ֮׷ط٦يأل٦أ⟃♴ך
    ٌآُ٦ٕ׾ׅץגٗ٦سׅ׷

    View Slide

  33. use Module::Find qw/useall/;
    useall('Foo::Handler');
    .PEVMF'JOE
    'PP)BOEMFS⟃♴ח֮׷
    'PP)BOEMFS"װ'PP)BOEMFS"#׾ٗ٦س

    View Slide

  34. 5ZQF5JOZ׾
    ⢪׏ג㘗׾⢪ֲ

    View Slide

  35. ؝٦سָ竰ֺ駈ׁ׸גְ׏׋
    ذأزךقٕػ

    View Slide

  36. sub create_xxx {
    my (%args) = @_;
    if ($args{foo}) { ... }
    db->insert(
    x => 100,
    y => 'abc',
    %args,
    );
    }
    ְ׹׿זךָ床ׇ׷
    剑穄涸חכ湫䱸床׃ג׃תֲ
    ㄎן⳿׃⩎חׅץג㨻י׷

    View Slide

  37. UZQPח䓲ְ
    ⢪ְ倯ָⴓַ׵זְךד
    ְ׹ְ׹鋅חְֻ

    View Slide

  38. 床׏גֹ׋䒷侧׾
    ثؑحؙׅ׷

    View Slide

  39. ֿ׿זהֹחכغٔر٦ة
    䗳갭ػًٓ٦ةָ床ׁ׸גְ׷ַ
    㘗ثؑحؙ

    View Slide

  40. use Params::Validate qw(:all);
    sub foo {
    my %args = validate(@_, {
    foo => { type => ARRAYREF },
    bar => { isa => 'Bar' },
    });
    }
    1BSBNT7BMJEBUF

    View Slide

  41. use Data::Validator;
    sub foo {
    state $rule = Data::Validator->new(
    foo => { isa => 'ArrayRef' },
    bar => { isa => 'Bar' },
    );
    my $args = $rule->validate(@_);
    }
    %BUB7BMJEBUPS
    .PVTFך㘗
    غٔر٦ةך㹀纏ךٍؗحءָُ〳腉
    「ֽ《׏׋ػًٓ٦ةכIBTISFGד乼⡲

    View Slide

  42. use Smart::Args;
    sub foo {
    args my $foo => 'ArrayRef',
    my $bar => 'Bar',
    ;
    }
    4NBSU"SHT
    [email protected]׾床ׅ䗳銲ָזְ
    غٔر٦ةך㹀纏׾ٍؗحءُדֹזְ
    「ֽ《׏׋ػًٓ٦ةכ㢌侧ד乼⡲

    View Slide

  43. View Slide

  44. [email protected]׾床ׁ׆חㄎן⳿׃⯋ך[email protected]׾《׸׷
    1BE8BMLFS׾⢪ְծ床׃׋㢌侧せ׾《׶⳿ׅ

    View Slide

  45. use Mouse::Util::TypeConstraints;
    my $type =
    find_or_create_isa_type_constraint('Int');
    $type->check($x);
    ⰻ鿇דכ.PVTFך㘗׾䪔ֲ

    View Slide

  46. 5ZQF5JOZ

    View Slide

  47. 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✼䳔

    View Slide

  48. 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✼䳔

    View Slide

  49. .PVTFה5ZQF5JOZך麩ְ

    View Slide

  50. use Mouse::Util::TypeConstraints;
    subtype 'NonEmptyStr',
    as 'Str',
    where { length($_) > 0 };
    my $type = find_type_constraint('NonEmptyStr');
    $type->check('str');
    .PVTF
    ؚٗ٦غٕז㘗׾㹑鎉

    View Slide

  51. use Type::Standard -types;
    use Type::Utils -all;
    subtype 'NonEmptyStr',
    as Str,
    where { length($_) > 0 };
    NonEmptyStr->check('str');
    5ZQF5JOZ
    ׉ך㜥ד㘗ךؔـآؙؑز׾⡲䧭
    㢩鿇ַ׵⢪ֲ㜥さכFYQPSUׇׁ׷

    View Slide

  52. 4NBSU"SHT5ZQF5JOZ
    4NBSU"SHTד5ZQF5JOZך㘗׾
    䪔ִ׷״ֲח׃׋׮ך
    4NBSU"SHTה㢌׻׵׆⢪ִ׷

    View Slide

  53. 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ד㹑鎉׃׋㘗׮⢪ִ׷

    View Slide

  54. use Types::Standard qw/Str/;
    use Params::ValidationCompiler;
    sub foo {
    state $validator = validation_for(
    params => {
    foo => { type => Str },
    },
    );
    my %args = $validator->(@_);
    }
    1BSBNT7BMJEBUJPO$PNQJMFS

    View Slide

  55. 倜׃ְ1FSMך
    堣腉׾⢪ֲ

    View Slide

  56. QPTUYEFSFGFSFODF
    QFSM⟃꣬ד姻䒭堣腉⻉

    View Slide

  57. $$a $a->$*
    @$a $a->@*
    $#$a $a->$#*
    %$a $a->%*
    &$a $a->&*
    *$a $a->**

    View Slide

  58. $$a $a->$*
    @$a $a->@*
    $#$a $a->$#*
    %$a $a->%*
    &$a $a->&*
    *$a $a->**

    View Slide

  59. my $x = {a => [1, 2, 3], b => [4]};
    兛鸐ךEFSFGFSFODF
    @{$x->{a}} $x->{a}->@*
    QPTUYEFSFGFSFODF

    View Slide

  60. map { $_->id } @{ Foo->bar(
    ...
    ) };
    map { $_->id } Foo->bar(
    ...
    )->@*;
    兛鸐ךEFSFGFSFODF
    QPTUYEFSFGFSFODF

    View Slide

  61. use constant A => [1, 2, 3];
    !"דכזְ׋׭"
    ד
    ㄎן⳿׃גֶֻ䗳銲ָ֮׷
    兛鸐ךEFSFGFSFODF
    @{A()}
    A->@*
    QPTUYEFSFGFSFODF
    @{+A}

    View Slide

  62. QFSM
    ׉׸⟃⵸ד׮⢪ְ׋ְ

    View Slide

  63. QPTUYEFSFGFSFODF׾㢌䳔
    [email protected]YEFSFG

    View Slide

  64. 11*׾⢪׏ג
    WBS!׾!WBSח
    剅ֹ䳔ִ׷

    View Slide

  65. ➙ּׅQPTUYEFSFGFSFODF
    ⢪ִ׷

    View Slide

  66. ֶ׻׶

    View Slide

  67. 5.5085%*
    5IFSFT.PSF5IBO0OF8BZ5P%P*U

    View Slide