Slide 1

Slide 1 text

ଟ૬ܕɺ ਪ࿦ɺ Ruby দຊफଠ࿠
 @soutaro

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

ܕ͸ॻ͖ͨ͘ͳ͍

Slide 5

Slide 5 text

ܕ͸ॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠

Slide 6

Slide 6 text

ܕ͸ॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠ ܕਪ࿦

Slide 7

Slide 7 text

ܕ͸ॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠ ܕਪ࿦ typo͙Β͍͸࣮ߦ͠ͳͯ͘΋ൃݟ͍ͨ͠

Slide 8

Slide 8 text

ܕ͸ॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠ ܕਪ࿦ typo͙Β͍͸࣮ߦ͠ͳͯ͘΋ൃݟ͍ͨ͠ ܕ͸ઈରʹॻ͖ͨ͘ͳ͍

Slide 9

Slide 9 text

ܕ͸ॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠ ܕਪ࿦ typo͙Β͍͸࣮ߦ͠ͳͯ͘΋ൃݟ͍ͨ͠ ܕ͸ઈରʹॻ͖ͨ͘ͳ͍ Gradual Typing

Slide 10

Slide 10 text

ͳΜ͔ྑ͍ײ͡ʹܕ͕͍ͭͨ Ruby͕ཉ͍͠ ܕ͸ॻ͖ͨ͘ͳ͍ Duck Typingʹͳ͍ͬͯͯཉ͍͠ ܕਪ࿦ typo͙Β͍͸࣮ߦ͠ͳͯ͘΋ൃݟ͍ͨ͠ ܕ͸ઈରʹॻ͖ͨ͘ͳ͍ Gradual Typing

Slide 11

Slide 11 text

զʑ͕ཉ͍͠΋ͷ ͳΜ͔ྑ͍ײ͡ʹܕ͕͍ͭͨRuby͕ཉ͍͠ ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬
 ׬શͳܕਪ࿦Ruby

Slide 12

Slide 12 text

ଟ૬ܕ w ύϥϝʔλଟ૬Parametric Polymorphism w ෦෼ܕଟ૬Subtyping Polymorphism w ΞυϗοΫଟ૬Ad-hoc Polymorphism จ຺ʹԠͯ͡ɺҰఆͷ੍ݶͷݩͰɺ
 ࣜʹ͍Ζ͍ΖͳܕΛ༩͑Δ

Slide 13

Slide 13 text

෦෼ܕଟ૬ w ෦෼ܕ
 “String is a Object” interface X { void f(Object x); } X x = …; x.f("Ruby"); x.f(new ArrayList());

Slide 14

Slide 14 text

෦෼ܕଟ૬ w ෦෼ܕ
 “String is a Object” interface X { void f(Object x); } X x = …; x.f("Ruby"); x.f(new ArrayList()); Ҿ਺ͷܕ͸String

Slide 15

Slide 15 text

෦෼ܕଟ૬ w ෦෼ܕ
 “String is a Object” interface X { void f(Object x); } X x = …; x.f("Ruby"); x.f(new ArrayList()); Ҿ਺ͷܕ͸String Ҿ਺ͷܕ͸ArrayList

Slide 16

Slide 16 text

໊લతɾߏ଄త w ໊લతNominal
 ΫϥεఆٛͰએݴͯ͠෦෼ܕؔ܎Λఆٛ w ߏ଄తStructual
 ϝιουఆٛͷแؚؔ܎Ͱ෦෼ܕؔ܎ΛఆٛʢΑΓ ॊೈʣ

Slide 17

Slide 17 text

ܕਪ࿦ w ʢ׬શͳʣܕਪ࿦ w ϩʔΧϧܕਪ࿦

Slide 18

Slide 18 text

ʢ׬શͳʣܕਪ࿦ [Milner, 1978] w શ͘ܕΛॻ͔ͳͯ͘΋ྑ͍
 ʢܕਪ࿦ͷ׬શੑCompletenessʣ w ϓϩάϥϛϯάݴޠ΁ͷ੍໿͕େ͖͍ʢMLʣ # let has_even_leaf tree = exists_leaf (fun n -> n mod 2 = 0) tree;; val has_even_leaf : tree -> bool =

Slide 19

Slide 19 text

ϩʔΧϧܕਪ࿦ [Pierce, 1997] w ϩʔΧϧม਺ͷܕ͸ॻ͔ͳͯ͘΋ྑ͍
 ϝιουͱ͔ͷܕ͸ॻ͘ɻ w ͍ΖΜͳϓϩάϥϛϯάݴޠʹಋೖͰ͖Δ
 ʢScala/Swift/C#/C++ʣ func greet(person: String) -> String { let greeting = "Hello, " + person + "!" return greeting }

Slide 20

Slide 20 text

ϩʔΧϧܕਪ࿦ [Pierce, 1997] w ϩʔΧϧม਺ͷܕ͸ॻ͔ͳͯ͘΋ྑ͍
 ϝιουͱ͔ͷܕ͸ॻ͘ɻ w ͍ΖΜͳϓϩάϥϛϯάݴޠʹಋೖͰ͖Δ
 ʢScala/Swift/C#/C++ʣ func greet(person: String) -> String { let greeting = "Hello, " + person + "!" return greeting } greetingͷܕ͸ਪ࿦͞ΕΔ

Slide 21

Slide 21 text

ϩʔΧϧܕਪ࿦ [Pierce, 1997] w ϩʔΧϧม਺ͷܕ͸ॻ͔ͳͯ͘΋ྑ͍
 ϝιουͱ͔ͷܕ͸ॻ͘ɻ w ͍ΖΜͳϓϩάϥϛϯάݴޠʹಋೖͰ͖Δ
 ʢScala/Swift/C#/C++ʣ func greet(person: String) -> String { let greeting = "Hello, " + person + "!" return greeting } greetingͷܕ͸ਪ࿦͞ΕΔ ؔ਺ͷܕ͸ॻ͘

Slide 22

Slide 22 text

զʑ͕ཉ͍͠΋ͷ ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬
 ׬શͳܕਪ࿦Ruby ͳΜ͔ྑ͍ײ͡ʹܕ͕͍ͭͨRuby͕ཉ͍͠

Slide 23

Slide 23 text

OCamlͳΜ͔͍ۙͷͰ͸ ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬
 ׬શͳܕਪ࿦Ruby # let f x = print_string x#to_s;; val f : < to_s : string; .. >
 -> unit =

Slide 24

Slide 24 text

OCamlͳΜ͔͍ۙͷͰ͸ ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬
 ׬શͳܕਪ࿦Ruby # let f x = print_string x#to_s;; val f : < to_s : string; .. >
 -> unit = #Ͱϝιουݺͼग़͠

Slide 25

Slide 25 text

OCamlͳΜ͔͍ۙͷͰ͸ ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬
 ׬શͳܕਪ࿦Ruby # let f x = print_string x#to_s;; val f : < to_s : string; .. >
 -> unit = to_sͱ͍͏ϝιου͕͋Ε͹ͳΜͰ΋͍͍ #Ͱϝιουݺͼग़͠

Slide 26

Slide 26 text

OCamlͰ͸μϝͳͱ͜Ζ w OCaml΋ΦϒδΣΫτͷपΓͰ͸ܕΛॻ͘ඞཁ͕ ͋Δ w OCamlͰ͸ॻ͚ͳ͍ϝιου w Array#map String#split

Slide 27

Slide 27 text

զʑ͕ཉ͍͠΋ͷ w ·ʔແཧ
 ͳʹ͔ΛఘΊͳ͍ͱ͍͚ͳ͍ɻ ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬
 ׬શͳܕਪ࿦Ruby

Slide 28

Slide 28 text

զʑ͕ཉ͍͠΋ͷ ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬
 ׬શͳܕਪ࿦Ruby

Slide 29

Slide 29 text

զʑ͕ཉ͍͠΋ͷ RubyͷػೳΛ੍ݶ͍ͯͬͯ͠ɺܕਪ࿦Ͱ͖ ΔΑ͏ʹͳΒͳ͍͔ʁʁ ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬
 ׬શͳܕਪ࿦Ruby

Slide 30

Slide 30 text

eval w ແཧ w evalͷฦΓ஋ͷܕ͸anyΈ͍ͨͳܕʹͯ͠͠·͑͹ ͍͍ͷͰ͸ʢGradual Typing [Siek and Taha, 2006]ʣ eval(gets)

Slide 31

Slide 31 text

ActiveRecord w DBʹ઀ଓ͠ͳ͍ͱΞτϦϏϡʔτ͕Θ͔Βͳ͍ w anyͰͳΜͱ͔͠Α͏ class Person < ApplicationRecord belongs_to :group has_many :contacts end

Slide 32

Slide 32 text

ϝλϓϩάϥϛϯά define_method(:name=) do |x| @attributes[:name] = x end

Slide 33

Slide 33 text

ϝλϓϩάϥϛϯά class Location attr_reader :line attr_reader :column end

Slide 34

Slide 34 text

require w require͕࣮ߦ͞ΕΔॠؒ·ͰͲͷϓϩάϥϜ͕ಡ· ΕΔ͔Θ͔Βͳ͍ w require͸ϝιουͳͷͰɺ࠶ఆٛͰ͖Δ͠ɺͲ͜ ʹͰ΋ॻ͚Δ͠ɺҾ਺ʹ͕ࣜॻ͚Δ w $LOAD_PATH΋͋ΔΑʂ w requireΛߏจʹͯ͠จࣈྻ͔͠ड͚औΕͳ͍ˍτο ϓϨϕϧʹ͔͠ॻ͚ͳ͍Α͏ʹ͢Ε͹ྑ͍ͷͰ͸

Slide 35

Slide 35 text

RubyGems ⚰Bundler

Slide 36

Slide 36 text

RubyΛ੍ݶͯ͠΋͏·͍͔͘ͳ͍ w ଞʹ΋໰୊͕͋Γɺݱ࣮తͳ੍ݶ͕ݟ͚ͭΒΕͳ͍ ʢࠓޙɺݟ͔ͭΔ͔΋͠Εͳ͍ʣ w ܕΛॻ͔ͳ͍લఏͰ͸ɺҰճanyʹࣦΘΕͨܕ৘ใ ΛऔΓ໭͢ํ๏͕ͳ͍

Slide 37

Slide 37 text

զʑ͕ཉ͍͠΋ͷ ύϥϝʔλଟ૬ߏ଄తͳ෦෼ܕଟ૬
 ׬શͳܕਪ࿦Ruby

Slide 38

Slide 38 text

͝ఏҊ w ߏ଄తͳ෦෼ܕଟ૬ϩʔΧϧܕਪ࿦Gradual Typing w ʢΘΓͱʣDuck TypingͰ͖ΔͷͰخ͍͠ w ॻ͔ͳͯ͘ྑ͍ܕ͸ॻ͔ͳ͍ w ܕ͕ॻ͍ͯͳ͍ͱ͖͸ࠓͷRubyͱಉ͡ w ܕͷͨΊͷݴޠ͸Rubyͱผ
 requireͱ͔ΦʔϓϯΫϥεͱ͔ϝλϓϩάϥϛϯάͱ ͔͸ߟ͑ͳ͍ɻ

Slide 39

Slide 39 text

͍͍ͩͨTypeScript

Slide 40

Slide 40 text

# group.rbi interface String def gsub: (Regexp, String) -> String end interface IGroup def people: ActiveRecord.Association end interface IPerson def email: String end # foo_controller.rb group: IGroup = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … }

Slide 41

Slide 41 text

# group.rbi interface String def gsub: (Regexp, String) -> String end interface IGroup def people: ActiveRecord.Association end interface IPerson def email: String end # foo_controller.rb group: IGroup = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … } ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ

Slide 42

Slide 42 text

# group.rbi interface String def gsub: (Regexp, String) -> String end interface IGroup def people: ActiveRecord.Association end interface IPerson def email: String end # foo_controller.rb group: IGroup = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … } ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ

Slide 43

Slide 43 text

# group.rbi interface String def gsub: (Regexp, String) -> String end interface IGroup def people: ActiveRecord.Association end interface IPerson def email: String end # foo_controller.rb group: IGroup = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … } ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ ܕ஫ऍ ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ

Slide 44

Slide 44 text

# group.rbi interface String def gsub: (Regexp, String) -> String end interface IGroup def people: ActiveRecord.Association end interface IPerson def email: String end # foo_controller.rb group: IGroup = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … } ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ ܕ஫ऍ ӈลͷܕ͕Θ͔ΔͷͰɺܕ஫ऍ͸ෆཁ ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ

Slide 45

Slide 45 text

# group.rbi interface String def gsub: (Regexp, String) -> String end interface IGroup def people: ActiveRecord.Association end interface IPerson def email: String end # foo_controller.rb group: IGroup = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … } ผͷϑΝΠϧͰɺΠϯλʔϑΣΠεΛએݴ͢Δ ܕ஫ऍ ӈลͷܕ͕Θ͔ΔͷͰɺܕ஫ऍ͸ෆཁ person.emailͷܕ͕StringͩͱΘ ͔ΔͷͰɺmap͕ͳ͍͜ͱ͕Θ͔Δ ΠϯλϑΣʔεʹϝιουͱܕΛએݴ͢Δ

Slide 46

Slide 46 text

ܕ஫ऍ͕ͳ͚Ε͹͜Ε·ͰͷRubyͱಉ͡ group = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … }

Slide 47

Slide 47 text

ܕ஫ऍ͕ͳ͚Ε͹͜Ε·ͰͷRubyͱಉ͡ group = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … } ܕ஫ऍ͕ͳ͍ͷͰશ෦anyʹͳΔԿ΋ݕࠪ͠ͳ͍

Slide 48

Slide 48 text

ܕ஫ऍ͕ͳ͚Ε͹͜Ε·ͰͷRubyͱಉ͡ group = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … } map͕ແ͍͜ͱ͸࣮ߦ࣌ʹൃ֮ ܕ஫ऍ͕ͳ͍ͷͰશ෦anyʹͳΔԿ΋ݕࠪ͠ͳ͍

Slide 49

Slide 49 text

# group.rbi interface String def gsub: (Regexp, String) -> String ... end interface IGroup def people: ActiveRecord.Association end interface IPerson def email: String end # foo_controller.rb group: IGroup = Group.create!(name: name) person = group.people.new escaped = person.email.map {|x| … }

Slide 50

Slide 50 text

– Rubyͷ෕Matz lܕ͸ઈରॻ͖ͨ͘ͳ͍z

Slide 51

Slide 51 text

w Group.create!ͷܕ͕GroupʹͳΔͷ͸Θ͔Βͳ͍ͷʁ
 Groupͷܕ͕Θ͔ΔͱࢥͬͯΔͷʁʁ w ܕΛҰͭ΋ॻ͍͍ͯͳ͍ͱͳʹ΋Θ͔Βͳ͍ͷʁʁ
 ϦςϥϧͳΜ͔͸Θ͔Δ͸ͣɻҙ֎ͱ͍Ζ͍Ζݟ͔ͭΔͷͰ͸ɻ w Ϋϥεఆٛʹ͸ܕΛॻ͚ͳ͍ͷʁΦʔϓϯΫϥε͸Ͳ͏ͳΔͷʁ
 ࠓޙͷ՝୊ɻΦʔϓϯΫϥεͱ0CKFDUJWF$ͷ$BUFHPSZͳΜ͔ ͸͍ۙؾ͕͢Δɻ w ࣮૷͸ͳ͍ͷʁ
 Α͘ݟΔͱɺʢܕ஫ऍΛίϝϯτͱ͔Ͱॻ͘͜ͱʹ͢Ε͹ʣ͙͢ ʹ࣮૷Ͱ͖Δͳ͜Εʜʜ