Slide 1

Slide 1 text

GitHub Linguistと学ぶ! 全国このコードは PerlとRakuどっちでしょう クイズ選手権大会 id:polamjag in YAPC::Hiroshima 2024 2

Slide 2

Slide 2 text

polamjag ポラムジャグ

Slide 3

Slide 3 text

4 提 供

Slide 4

Slide 4 text

5 ヒント forms.gle/ vJ392bhceahnE5bz7 受付終了 受付終了

Slide 5

Slide 5 text

6 大ヒント forms.gle/ vJ392bhceahnE5bz7 受付終了 受付終了

Slide 6

Slide 6 text

7 問1

Slide 7

Slide 7 text

8 use v6; use Test; use ***; use ***; plan 2; if %*ENV { diag "NO_NETWORK_TESTING was set"; skip-rest("NO_NETWORK_TESTING was set"); exit; } my %headers = "Accept" => "application/json", "User-Agent" => "...", ; (固有名詞などはマスク)

Slide 8

Slide 8 text

9 問2

Slide 9

Slide 9 text

10 use strict; use warnings; use ****::****; # (略) subtest 'request_send' => sub { my $ua = ua; my $res = $ua->get('http://www.example.com'); ok($res->is_success, 'handler should succeed'); is($res->content,'ok','handler-provided response should be used'); }; subtest 'request_prepare' => sub { my $ua = ua; $ua->add_handler( request_prepare => sub { # the docs say this is the way to replace the request $_[0] = HTTP::Request->new(POST=>'http://mmm.example.com/'); (固有名詞などはマスク)

Slide 10

Slide 10 text

11 問3

Slide 11

Slide 11 text

12 use v6; use Test; use Auth::SASL; my $sasl = Auth::SASL.new; ok $sasl, 'got an object'; isa-ok $sasl, Auth::SASL; ok $sasl.supports-client-mechanisms('PLAIN'), 'supports PLAIN'; ok $sasl.supports-client-mechanisms('ANONYMOUS'), 'supports ANONYMOUS'; ok $sasl.supports-client-mechanisms('PLAIN ANONYMOUS'), 'supports PLAIN ANONYMOUS'; ok $sasl.supports-client-mechanisms('PLAIN WEIRD'), 'supports PLAIN WEIRD'; nok $sasl.supports-client-mechanisms('SUPER WEIRD'), 'does not supoprt SUPER WEIRD'; (固有名詞などはマスク)

Slide 12

Slide 12 text

13 問4

Slide 13

Slide 13 text

14 use v6; use Test; use BSON; # (略) #------------------------------------------------------------------------------ - subtest { my BSON::Javascript $js .= new( :javascript('function(x){return x;}') ); my BSON::Javascript $js-scope .= new( :javascript('function(x){return x;}'), :scope(BSON::Document.new: (nn => 10, a1 => 2)) ); (固有名詞などはマスク)

Slide 14

Slide 14 text

15 問5

Slide 15

Slide 15 text

16 use Test; plan 6; use Digest::HMAC; use Digest::MD5; use Digest::SHA1; use Digest::SHA2; # tests taken from wikipedia is hmac-hex("", "", &md5), '74e6f7298a9c2d168935f58c001bad88', "Empty md5 HMAC"; is hmac-hex("", "", &sha1), 'fbdb1d1b18aa6c08324b7d64b71fb76370690e1d', "Empty SHA1 HMAC"; is hmac-hex("", "", &sha256), 'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad', "Empty SHA256 HMAC";

Slide 16

Slide 16 text

17 終

Slide 17

Slide 17 text

問題の出典 1. https://github.com/raku-community-modules/LWP-Simple/blob/71 38dbe75b2d6593e69fc707997b7abd25fa36fc/t/put-request.t 2. https://github.com/libwww-perl/libwww-perl/blob/bfcf2c43bbb6 d22ed9422550d304f95dcae0d195/t/base/ua_handlers.t 3. https://github.com/zostay/raku-Auth-SASL/blob/e2fdecc0124ab0 fcaa74acd7a3880163b0e230e9/t/supports.t 4. https://github.com/MARTIMM/BSON/blob/113ea0a93c30f50a3478741 529b3987575a3747b/t/Document-all-types.t 5. https://github.com/JJ/Raku-Digest-HMAC/blob/9bae022a49c14ab9 2a059d7a0d5aa95c4026c27f/t/01-basic.t 18

Slide 18

Slide 18 text

19 解説

Slide 19

Slide 19 text

github-linguist/linguist 20

Slide 20

Slide 20 text

21

Slide 21

Slide 21 text

22

Slide 22

Slide 22 text

23

Slide 23

Slide 23 text

24 # A strategy should return an Array of Language candidates. # # Strategies are called in turn until a single Language is re STRATEGIES = [ Linguist::Strategy::Modeline, Linguist::Strategy::Filename, Linguist::Shebang, Linguist::Strategy::Extension, Linguist::Strategy::XML, Linguist::Strategy::Manpage, Linguist::Heuristics, Linguist::Classifier ] … cpanfile は Perl、.irbrc は Ruby など

Slide 24

Slide 24 text

25 returning_strategy = nil STRATEGIES.each do |strategy| returning_strategy = strategy candidates = Linguist.instrument("linguist.strategy", :blob => blob, :str strategy.call(blob, languages) end if candidates.size == 1 languages = candidates break elsif candidates.size > 1 # More than one candidate was found, pass them to the next strategy. languages = candidates else # No candidates, try the next strategy end end

Slide 25

Slide 25 text

lib/linguist/languages.yml 26

Slide 26

Slide 26 text

27

Slide 27

Slide 27 text

languages.yml 712種類 データファイル (JSONなど) 159 マークアップ (HTMLなど) 61 プログラミング言語 474 文章 (Markdown・Podなど) 18 28

Slide 28

Slide 28 text

29

Slide 29

Slide 29 text

lib/linguist/heuristics.yml 30

Slide 30

Slide 30 text

31 - extensions: ['.t'] rules: - language: Perl and: - negative_pattern: '^\s*use\s+v6\b' - named_pattern: perl - language: Raku pattern: '^\s*(?:use\s+v6\b|\bmodule\b|\bmy\s+class\b)'

Slide 31

Slide 31 text

32

Slide 32

Slide 32 text

33

Slide 33

Slide 33 text

use VERSION pragma (今風に言うと) リリースバージョンに紐づいた デカfeature flag 34

Slide 34

Slide 34 text

35 - extensions: ['.t'] rules: - language: Perl and: - negative_pattern: '^\s*use\s+v6\b' - named_pattern: perl - language: Raku pattern: '^\s*(?:use\s+v6\b|\bmodule\b|\bmy\s+class\b)'

Slide 35

Slide 35 text

36 - extensions: ['.t'] rules: - language: Perl and: - negative_pattern: '^\s*use\s+v6\b' - named_pattern: perl - language: Raku pattern: '^\s*(?:use\s+v6\b|\bmodule\b|\bmy\s+class\b)'

Slide 36

Slide 36 text

37 - extensions: ['.t'] rules: - language: Perl and: - negative_pattern: '^\s*use\s+v6\b' - named_pattern: perl - language: Raku pattern: '^\s*(?:use\s+v6\b|\bmodule\b|\bmy\s+class\b)' use v6 って書いてたら Perl 5じゃない (それはそう)

Slide 37

Slide 37 text

38 named_patterns: (snip) objectivec: '^\s*(@(interface|class|protocol|property|end|synchronise perl: - '\buse\s+(?:strict\b|v?5\b)' - '^\s*use\s+(?:constant|overload)\b' - '^\s*(?:\*|(?:our\s*)?@)EXPORT\s*=' - '^\s*package\s+[^\W\d]\w*(?:::\w+)*\s*(?:[;{]|\sv?\d)' - '[\s$][^\W\d]\w*(?::\w+)*->[a-zA-Z_\[({]' raku: '^\s*(?:use\s+v6\b|\bmodule\b|\b(?:my\s+)?class\b)' vb-class: '^[ ]*VERSION [0-9]\.[0-9] CLASS' vb-form: '^[ ]*VERSION [0-9]\.[0-9]{2}' vb-module: '^[ ]*Attribute VB_Name = ' vba: - '\b(?:VBA|[vV]ba)(?:\b|[0-9A-Z_])'

Slide 38

Slide 38 text

39 named_patterns: (snip) objectivec: '^\s*(@(interface|class|protocol|property|end|synchronise perl: - '\buse\s+(?:strict\b|v?5\b)' - '^\s*use\s+(?:constant|overload)\b' - '^\s*(?:\*|(?:our\s*)?@)EXPORT\s*=' - '^\s*package\s+[^\W\d]\w*(?:::\w+)*\s*(?:[;{]|\sv?\d)' - '[\s$][^\W\d]\w*(?::\w+)*->[a-zA-Z_\[({]' raku: '^\s*(?:use\s+v6\b|\bmodule\b|\b(?:my\s+)?class\b)' vb-class: '^[ ]*VERSION [0-9]\.[0-9] CLASS' vb-form: '^[ ]*VERSION [0-9]\.[0-9]{2}' vb-module: '^[ ]*Attribute VB_Name = ' vba: - '\b(?:VBA|[vV]ba)(?:\b|[0-9A-Z_])'

Slide 39

Slide 39 text

40 named_patterns: (snip) objectivec: '^\s*(@(interface|class|protocol|property|end|synchronise perl: - '\buse\s+(?:strict\b|v?5\b)' - '^\s*use\s+(?:constant|overload)\b' - '^\s*(?:\*|(?:our\s*)?@)EXPORT\s*=' - '^\s*package\s+[^\W\d]\w*(?:::\w+)*\s*(?:[;{]|\sv?\d)' - '[\s$][^\W\d]\w*(?::\w+)*->[a-zA-Z_\[({]' raku: '^\s*(?:use\s+v6\b|\bmodule\b|\b(?:my\s+)?class\b)' パッケージ (クラス) を定義する構文 メソッド呼び出しの構文 use strict 概念の有無

Slide 40

Slide 40 text

41 PerlとRakuのテストは 中身だけだと見分けにくいことがある 多数の秘伝のタレ的条件で判定 探してるとまだ誤判定は出てくる (!) たぶん誤判定があるレポジトリの例: https://github.com/pdf-raku/Font-FreeType-raku ただし、RakuのテストがPerl 5扱いされているのでちょっと違う話

Slide 41

Slide 41 text

Appendix 42

Slide 42

Slide 42 text

43 languages.yml基準 拡張子被りランキング 8c380f3 基準

Slide 43

Slide 43 text

44 .inc 11 .m 7 .fcgi 6 .cls 6 .sql 5 .pro 5 .yml 4 .yaml 4 .x 4 .t 4 .sch 4 .ncl 4 .mod 4 .l 4 .gs 4 .gml 4 .fs 4 .bf 4 .bas 4 languages.yml基準 拡張子被りランキング 8c380f3 基準

Slide 44

Slide 44 text

45 .inc 11 .m 7 .fcgi 6 .cls 6 .sql 5 .pro 5 .yml 4 .yaml 4 .x 4 .t 4 .sch 4 .ncl 4 .mod 4 .l 4 .gs 4 .gml 4 .fs 4 .bf 4 .bas 4 Assembly, C++, HTML, Motorola 68K Assembly, NASL, Pascal, Pawn, PHP, POV-Ray SDL, SourcePawn, SQL Lua, Perl, PHP, Python, Ruby, Shell Perl, Raku, Terra, Turing

Slide 45

Slide 45 text

46 https://github.com/mojolicious/mojo/pull/804

Slide 46

Slide 46 text

47

Slide 47

Slide 47 text

48