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

7a8922191c1fa60728589a3def4c179f?s=47 akiym
March 03, 2018

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

YAPC::Okinawa 2018 ONNASON

7a8922191c1fa60728589a3def4c179f?s=128

akiym

March 03, 2018
Tweet

Transcript

  1. 1FSM؝٦ر؍ؚٝ
 ذؙصحؙ BLJZN :"1$0LJOBXB0//"40/

  2. BLJZN

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

  4. 剑鵚ך1FSM歲꥔

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

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

  7. VTFTUSJDU

  8. VTFTUSJDU VTFXBSOJOHT VTFVUG

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

  10. VTFTUSJDUVSFT use strict; use warnings FATAL => 'all'; use warnings

    NONFATAL => qw( exec recursion internal malloc newline experimental deprecated portable ); no warnings 'once';
  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
  12. ؙٓأؽٕت

  13. sub new { my ($class, %args) = @_; croak("required: z")

    unless exists $args{z}; return bless \%args, $class; } sub z { $_[0]->{z} } CMFTT
  14. Ⰻ鿇䩛דװ׷崢

  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
  16. 堣腉搀꼽ח⢪ֲֶה׃ג 醱꧟חז׶ָ׍

  17. use Class::Tiny qw(x y z); sub BUILD { my ($self,

    $args) = @_; croak("required: z") unless exists $args->{z}; } $MBTT5JOZ
  18. 㼭ׁז׮ך׾ 穈׫さ׻ׇג⢪ֲ

  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
  20. 鵚➿涸 FYQPSU遭

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

    test.pl use Foo; foo();
  22. 倜׃ְꟼ侧ך鷄⸇䖓ח !&91035ח׮鷄⸇ׅ׷ך׾ 䘌׸ָ׍

  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׃׋ꟼ侧כ搀鋔 @ַ׵㨣ת׷ꟼ侧כ搀鋔
  24. *NQPSUFS use Importer Importer => 'import'; use Importer 'List::Util' =>

    ( any => {-as => 'list_util_any'}, ); VTF&YQPSUFSJNQPSUךַ׻׶ ⴽせדJNQPSUדֹ׷
  25. ٌآُ٦ٕ ٗ٦ت٦

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

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

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

  29. $MBTT-PBE USZ@MPBE@DMBTT ׅדחٗ٦س幥׫ַⴻ倖ׅ׷JT@DMBTT@MPBEFE

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

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

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

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

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

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

  36. sub create_xxx { my (%args) = @_; if ($args{foo}) {

    ... } db->insert( x => 100, y => 'abc', %args, ); } ְ׹׿זךָ床ׇ׷ 剑穄涸חכ湫䱸床׃ג׃תֲ ㄎן⳿׃⩎חׅץג㨻י׷
  37. UZQPח䓲ְ ⢪ְ倯ָⴓַ׵זְךד ְ׹ְ׹鋅חְֻ

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

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

  40. use Params::Validate qw(:all); sub foo { my %args = validate(@_,

    { foo => { type => ARRAYREF }, bar => { isa => 'Bar' }, }); } 1BSBNT7BMJEBUF
  41. use Data::Validator; sub foo { state $rule = Data::Validator->new( foo

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

    my $bar => 'Bar', ; } 4NBSU"SHT !@׾床ׅ䗳銲ָזְ غٔر٦ةך㹀纏׾ٍؗحءُדֹזְ 「ֽ《׏׋ػًٓ٦ةכ㢌侧ד乼⡲
  43. None
  44. !@׾床ׁ׆חㄎן⳿׃⯋ך!@׾《׸׷ 1BE8BMLFS׾⢪ְծ床׃׋㢌侧せ׾《׶⳿ׅ

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

  46. 5ZQF5JOZ

  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✼䳔
  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✼䳔
  49. .PVTFה5ZQF5JOZך麩ְ

  50. use Mouse::Util::TypeConstraints; subtype 'NonEmptyStr', as 'Str', where { length($_) >

    0 }; my $type = find_type_constraint('NonEmptyStr'); $type->check('str'); .PVTF ؚٗ٦غٕז㘗׾㹑鎉
  51. use Type::Standard -types; use Type::Utils -all; subtype 'NonEmptyStr', as Str,

    where { length($_) > 0 }; NonEmptyStr->check('str'); 5ZQF5JOZ ׉ך㜥ד㘗ךؔـآؙؑز׾⡲䧭 㢩鿇ַ׵⢪ֲ㜥さכFYQPSUׇׁ׷
  52. 4NBSU"SHT5ZQF5JOZ 4NBSU"SHTד5ZQF5JOZך㘗׾ 䪔ִ׷״ֲח׃׋׮ך 4NBSU"SHTה㢌׻׵׆⢪ִ׷

  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ד㹑鎉׃׋㘗׮⢪ִ׷
  54. use Types::Standard qw/Str/; use Params::ValidationCompiler; sub foo { state $validator

    = validation_for( params => { foo => { type => Str }, }, ); my %args = $validator->(@_); } 1BSBNT7BMJEBUJPO$PNQJMFS
  55. 倜׃ְ1FSMך 堣腉׾⢪ֲ

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

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

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

    *$a $a->**
  59. my $x = {a => [1, 2, 3], b =>

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

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

    兛鸐ךEFSFGFSFODF @{A()} A->@* QPTUYEFSFGFSFODF @{+A}
  62. QFSM ׉׸⟃⵸ד׮⢪ְ׋ְ

  63. QPTUYEFSFGFSFODF׾㢌䳔 IUUQTHJUIVCDPNBLJZNMFHBDZ@QPTUYEFSFG

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

  65. ➙ּׅQPTUYEFSFGFSFODF ⢪ִ׷

  66. ֶ׻׶

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