Slide 1

Slide 1 text

Tomokazu Kiyohara 2025/01/18(Sat) ๺཮ࡾݝ.rb Lightning Talks in Kanazawa ಡΊΔ͔ͳʁ ͪΐͬͱϨΞͳRubyͷه๏

Slide 2

Slide 2 text

🎉 Ruby 3.4 released at ’24/12/25

Slide 3

Slide 3 text

৽ه๏ it

Slide 4

Slide 4 text

it is "default block parameter" ref. Fe a ture #18980: `it` a s a def a ult block p a r a meter - Ruby m a ster - Ruby Issue Tr a cking System ( https://bugs.ruby-l a ng.org/issues/18980 )

Slide 5

Slide 5 text

ϒϩοΫύϥϝʔλ [1, 2, 3].map {|i| i * 10 } #=> [ 10, 20, 30 ]

Slide 6

Slide 6 text

ϒϩοΫύϥϝʔλ [1, 2, 3].map {|i| i * 10 } #=> [ 10, 20, 30 ]

Slide 7

Slide 7 text

"σϑΥϧτ" ϒϩοΫύϥϝʔλ [1, 2, 3].map {|i| i * 10 } [1, 2, 3].map { it * 10 } #=> [ 10, 20, 30 ]

Slide 8

Slide 8 text

"σϑΥϧτ" ϒϩοΫύϥϝʔλ [1, 2, 3].map {|i| i * 10 } [1, 2, 3].map { it * 10 } #=> [ 10, 20, 30 ]

Slide 9

Slide 9 text

it ͝࢖༻্ͷ஫ҙʹ͍ͭͯ

Slide 10

Slide 10 text

it ͝࢖༻্ͷ஫ҙʹ͍ͭͯ [1, 2, 3].map { it * 10 } #=> [ 10, 20, 30 ] it = 9 [1, 2, 3].map { it * 10 } #=> [ 90, 90, 90 ] ϒϩοΫ֎Ͱ it Λఆ͍ٛͯ͠Δͱ ϒϩοΫ಺ͷ it ͸౰֘ม਺ͱͯ͠ॲཧ͞ΕΔ

Slide 11

Slide 11 text

• αϯϓϧίʔυͰΘ͔ΔʂRuby 3.4ͷओͳ৽ػೳͱมߋ఺ P a rt 2ɾ৽ ػೳͱมߋ఺ͷ૯·ͱΊ #R a ils - Qiit a • https://qiit a .com/jnchito/items/ e a db5f96e0fd ff 01bd71#%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%81%AE%E3 %83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%8 2%BF%E3%81%A8%E3%81%97%E3%81%A6-it- %E3%81%8C%E8%BF%BD%E5%8A%A0%E3%81%95%E3%82%8C%E3%81%9F • ϓϩͱಡΈղ͘Ruby 3.4 NEWS - STORES Product Blog • https://product.st.inc/entry/2024/12/25/154728 it ਂ۷Γ

Slide 12

Slide 12 text

ͪͳΈʹ

Slide 13

Slide 13 text

default block parameter it ͷɺ͞Βʹલ

Slide 14

Slide 14 text

numbered block parameter (Ruby 2.7 ~) ref. Ruby 2.7 ch a nges - Ruby Ch a nges ( https://rubyreferences.github.io/rubych a nges/2.7.html#numbered-block-p a r a meters )

Slide 15

Slide 15 text

"φϯόʔυ" ϒϩοΫύϥϝʔλ [[1,2],[10,20]].map{|a, b| a*b } #=> [ 10, 40 ] [[1,2],[10,20]].map{ _1 * _2 } #=> [ 10, 40 ]

Slide 16

Slide 16 text

"φϯόʔυ" ϒϩοΫύϥϝʔλ [[1,2],[10,20]].map{|a, b| a*b } #=> [ 10, 40 ] [[1,2],[10,20]].map{ _1 * _2 } #=> [ 10, 40 ]

Slide 17

Slide 17 text

it ͸ _1 ʹผ໊͕͍ͭͨ ͱ΋ݴ͑Δ ҰํͰ it ͱ _2 ΛಉҰϒϩοΫ಺ʹॻ͚ͳ͍ͱ͍ͬͨ ੍໿΋͋ͬͨΓ͢Δ

Slide 18

Slide 18 text

• Ruby: "uselessγϯλοΫεγϡΨʔ"γϦʔζ: numbered block p a r a metersʢ຋༁ʣʛTechR a cho by BPSגࣜձࣾ • https://techr a cho.bpsinc.jp/h a chi8833/2024_01_22/136901 numbered block parameter ਂ۷Γ

Slide 19

Slide 19 text

͍Ζ͍Ζͳॻ͖ํΛ஌͓ͬͯ͘ͱ ίʔυϨϏϡʔ΋͸͔ͲΔ ʢ͔΋͠Εͳ͍ʣ

Slide 20

Slide 20 text

ͪΐͬͱϨΞͳ Ruby ͷॻ͖ํ ͍Ζ͍Ζ ʢϨΞϦςΟ͸ݸਓͷײ૝Ͱ͢ʣ

Slide 21

Slide 21 text

஫ҙ ϨΞϦςΟͱ ॻ͖΍͢͞΍ಡΈ΍͢͞͸ ผ෺

Slide 22

Slide 22 text

஫ҙ ࠓ೔ͷϨΞϦςΟ͸ ໌೔ʹ͸มΘ͍ͬͯ͘ ʢࠓޙͲΜͲΜݟΔΑ͏ʹͳΔ͔΋ʣ

Slide 23

Slide 23 text

Let's go

Slide 24

Slide 24 text

html = %Q{

} colors = %w[red blue green] regex = %r{https?://[\w.-]+} ϨΞϦςΟɿ˒

Slide 25

Slide 25 text

% ه๏ ref. Ϧςϥϧ (Ruby 3.4 ϦϑΝϨϯεϚχϡΞϧ) ( https://docs.ruby-l a ng.org/j a /l a test/doc/spec=2 f liter a l.html#percent )

Slide 26

Slide 26 text

% ه๏ % %Q %(a b #{1 + 2}) %Q(a b #{1 + 2}) "a b #{1 + 2}" "a b 3" %q %q(a b #{1 + 2}) 'a b #{1 + 2}' "a b \#{1 + 2}" %x %x(ls -a) `ls -a` ".\n..\n.git\nREADME\n" %r %r([A-z]+$) /[A-z]+$/ /[A-z]+$/ %w %w(a b #{1 + 2}) ['a', 'b', '#{1', '+', '2}'] ["a", "b", "\#{1", "+", "2}"] %W %W(a b #{1 + 2}) ["a", "b", "#{1 + 2}"] ["a", "b", "3"] %s %s(a b #{1 + 2}) :'a b #{1 + 2}' :"a b \#{1 + 2}" %i %i(a b #{1 + 2}) [:a, :b, :'#{', :+, :'2}'] [:a, :b, :"\#{", :+, :"2}"] %I %I(a b #{1 + 2}) [:a, :b, :"#{1 + 2}"] [:a, :b, :"3"]

Slide 27

Slide 27 text

% ه๏ • ΤεέʔϓॲཧΛল͚Δͷ͕ར఺ • ॻ͖΍͢͞ͱ͍͏ΑΓ΋ಡΈ΍͢͞ • %() ͷ () ෦ʢσϦϛλʣ͸͍Ζ͍Ζͳ΋ͷʹஔ͖׵͑Մೳ • {} [] () <> # ͳͲͳͲ

Slide 28

Slide 28 text

next

Slide 29

Slide 29 text

val = foo&.bar&.baz ϨΞϦςΟɿ˒

Slide 30

Slide 30 text

Safe navigation operator a.k.a. ΅ͬͪԋࢉࢠ (Ruby 2.3~) ref. Fe a ture #11537: Introduce "S a fe n a vig a tion oper a tor" - Ruby m a ster - Ruby Issue Tr a cking System ( https://bugs.ruby-l a ng.org/issues/ 11537 )

Slide 31

Slide 31 text

val = foo&.bar&.baz bar = foo.nil? ? nil : foo.bar val = bar.nil? ? nil : bar.baz Safe navigation operator Ϩγʔό͕ nil ͷ৔߹ ɾҾ਺ͷධՁ͕ߦͳΘΕͳ͍ ɾϝιουݺͼग़͕͠ߦΘΕͳ͍ ɾnil Λฦ͢

Slide 32

Slide 32 text

foo&.bar = val unless foo.nil? foo.bar = val end Safe navigation operator ୅ೖʹ΋ར༻Մೳ

Slide 33

Slide 33 text

next

Slide 34

Slide 34 text

%w[a b c].map(&:upcase) ϨΞϦςΟɿ˒˒

Slide 35

Slide 35 text

SymbolProc ref. Cl a ss: RuboCop::Cop::Style::SymbolProc — Document a tion for bb a tsov/RuboCop (m a ster) ( https://www.rubydoc.info/github/bb a tsov/ RuboCop/RuboCop/Cop/Style/SymbolProc ) ref. Ruby: Ξϯύαϯυͱίϩϯ`&:`ه๏ʹ͍ͭͯௐ΂ͯΈͨʛTechR a cho by BPSגࣜձࣾ https://techr a cho.bpsinc.jp/ h a chi8833/2021_05_27/66735

Slide 36

Slide 36 text

['a','b','c'].map(&:upcase) => ["A", "B", "C"] ['a','b','c'].map {|i| i.upcase} => ["A", "B", "C"] &:symbol & (Proc coercion) ͱ :symbol ͷ૊Έ߹Θͤ ʢ&: ͱ͍͏ԋࢉࢠͱ͍͏Θ͚Ͱ͸ͳ͍ʣ

Slide 37

Slide 37 text

next

Slide 38

Slide 38 text

def foo(k1:, k2:, **kwrest) end # different from below # def foo(k1, k2, *rest) end ϨΞϦςΟɿ˒˒

Slide 39

Slide 39 text

double splat parameter ref. Ϋϥεʗϝιουͷఆٛ (Ruby 3.4 ϦϑΝϨϯεϚχϡΞϧ) ( https://docs.ruby-l a ng.org/j a /3.4/doc/spec=2fdef.html#method )

Slide 40

Slide 40 text

def foo(k1:, k2:, **kwrest) end foo(k1:'a', k2:'b', k3:'c', k4:'d') # kwrest => { k3:'c', k4:'d' } double splat parameter keyword Ҿ਺ͷʮ࢒Γશ෦ʯ *rest ͰҐஔҾ਺ͷʮ࢒Γશ෦ʯΛड͚Δͷͱ΄΅ಉ͡ def foo( a , b, *rest)

Slide 41

Slide 41 text

next

Slide 42

Slide 42 text

my_hash = { v1:, v2: } val = my_func(v1:, v2:) ϨΞϦςΟɿ˒˒˒

Slide 43

Slide 43 text

Hash & Keyword Ҿ਺ͷʮলུʯ (Ruby 3.1~) ref. Ruby 3.1 ch a nges - Ruby Ch a nges ( https://rubyreferences.github.io/rubych a nges/3.1.html#v a lues-in-h a sh-liter a ls- a nd-keyword- a rguments-c a n-be-omitted )

Slide 44

Slide 44 text

h = { x:, y: } # { x: x, y: y } と同じ foo(x:, y:) # (x: x, y: y) と同じ Hash & Keyword Ҿ਺ͷʮলུʯ key ͱಉ໊ͷม਺ࢀর͸লུԽ puts σόοά࣌ͳͲʹ΋ศར p x:, y:

Slide 45

Slide 45 text

next

Slide 46

Slide 46 text

def f(x, y) = x + y ϨΞϦςΟɿ˒˒˒

Slide 47

Slide 47 text

“Endless” method de fi nition (Ruby 3.0~) ref. Ruby 3.0 ch a nges - Ruby Ch a nges ( https://rubyreferences.github.io/rubych a nges/3.0.html#endless-method-de f inition )

Slide 48

Slide 48 text

def available? [email protected]? end def available? = [email protected]? “Endless” method de fi nition 1ߦͰؔ਺Λఆٛ

Slide 49

Slide 49 text

next

Slide 50

Slide 50 text

[BASE_URL, path].join('/') .then { URI.open(it).read } .then { JSON.parse(it) } .dig('owner' ) .then { it.to_yaml } .then { File.write('out.yml', it) } ϨΞϦςΟɿ˒˒˒˒

Slide 51

Slide 51 text

then ԋࢉࢠ (Ruby 2.6~) ref. Ruby 2.6 ch a nges - Ruby Ch a nges ( https://rubyreferences.github.io/rubych a nges/2.6.html#then- a s- a n- a li a s-for-yield_self )

Slide 52

Slide 52 text

Ruby 2.4 Ҏલͷॻ͖ํ path = [BASE_URL, path].join('/') json = URI.open(path).read content = JSON.parse(json) owner = content.dig('owner') yaml = owner.to_yaml File.write('out.yml', yaml)

Slide 53

Slide 53 text

#yield_self (Ruby 2.5~) [BASE_URL, path].join('/') .yield_self {|path| URI.open(path).read } .yield_self {|json| JSON.parse(json) } .dig('owner') .yield_self {|owner| owner.to_yaml } .yield_self {|yaml| File.write('out.yml',yaml) } ࣗ਎ΛҾ਺ʹϒϩοΫΛ࣮ߦ & ϒϩοΫͷ݁ՌΛฦ͢

Slide 54

Slide 54 text

#yield_self ͷผ໊ #then [BASE_URL, path].join('/') .then {|path| URI.open(path).read } .then {|json| JSON.parse(json) } .dig('owner') .then {|owner| owner.to_yaml } .then {|yaml| File.write('out.yml',yaml) } #tap ͱ͍͏ྨࣅϝιου΋͋Δ ʢࣗ਎ΛҾ਺ʹϒϩοΫΛ࣮ߦ & ࣗ਎Λฦ͢ʣ

Slide 55

Slide 55 text

it ͱͷ૊Έ߹Θͤ [BASE_URL, path].join('/') .then { URI.open(it).read } .then { JSON.parse(it) } .dig('owner' ) .then { it.to_yaml } .then { File.write('out.yml', it) }

Slide 56

Slide 56 text

next

Slide 57

Slide 57 text

def wrap_f1(&) = f1(&) def wrap_f2(*) = f2(*) def wrap_f3(**) = f3(**) ϨΞϦςΟɿ˒˒˒˒˒

Slide 58

Slide 58 text

Anonymous block argument (Ruby 3.1~) & Anonymous arguments passing (Ruby 3.2~) ref. Ruby 3.1 ch a nges - Ruby Ch a nges ( https://rubyreferences.github.io/rubych a nges/3.1.html# a nonymous-block- a rgument ) ref. Ruby 3.2 ch a nges - Ruby Ch a nges ( https://rubyreferences.github.io/rubych a nges/3.2.html# a nonymous- a rguments-p a ssing- improvements )

Slide 59

Slide 59 text

def wrap_f1(&) = f1(&) # ブロック引数 def wrap_f2(*) = f2(*) # 全位置引数 def wrap_f3(**) = f3(**) # 全キーワード引数 def wrap_f4(*, **) f4_1(*) f4_2(**) end # こういった書き方も出来る શҾ਺Λͦͷ··ผͷϝιου΁

Slide 60

Slide 60 text

next

Slide 61

Slide 61 text

if user in { name:, role: } puts %(#{name} is #{role}) end ϨΞϦςΟɿ˒˒˒˒˒˒

Slide 62

Slide 62 text

Pattern matching (in) (Ruby 2.7~) ref. Ruby 2.7 ch a nges - Ruby Ch a nges ( https://rubyreferences.github.io/rubych a nges/2.7.html#p a ttern-m a tching ) ref. p a ttern_m a tching - Document a tion for Ruby 3.5 ( https://docs.ruby-l a ng.org/en/m a ster/synt a x/p a ttern_m a tching_rdoc.html )

Slide 63

Slide 63 text

ύλʔϯϚονϯά • P a ttern m a tching is a fe a ture a llowing deep m a tching of structured v a lues: checking the structure a nd binding the m a tched p a rts to loc a l v a ri a bles. • ύλʔϯϚονϯά͸ωετΛؚΉσʔλߏ଄ͷϚονϯάΛՄೳʹ ͢Δػೳ • σʔλߏ଄Λ֬ೝ͢Δ (checking) • Ұகͨ͠෦෼ΛϩʔΧϧม਺ʹׂΓ౰ͯΔ (binding)

Slide 64

Slide 64 text

if user in { name:, role: } puts %(#{name} is #{role}) end Pattern matching (in) in ۟ͷޙʹ Hash Λهड़͢Δ͜ͱͰ ߏ଄ͷνΣοΫͱม਺΁ͷ୅ೖΛಉ࣌ʹߦ͍ͬͯΔ ͜͜Ͱ {name:, role:} ͸লུه๏ {name:n, role:r} ͱॻ͍ͨ৔߹͸ม਺ n,r ͕ఆٛ͞ΕΔ

Slide 65

Slide 65 text

next

Slide 66

Slide 66 text

user => { name:, role: } puts %(#{name} is #{role}) ϨΞϦςΟɿ˒˒˒˒˒˒

Slide 67

Slide 67 text

Pattern matching (=>) (Ruby 3.0~) ref. Ruby 3.0 ch a nges - Ruby Ch a nges ( https://rubyreferences.github.io/rubych a nges/3.0.html#p a ttern-m a tching ) ref. p a ttern_m a tching - Document a tion for Ruby 3.5 ( https://docs.ruby-l a ng.org/en/m a ster/synt a x/p a ttern_m a tching_rdoc.html )

Slide 68

Slide 68 text

user => { name:, role: } puts %(#{name} is #{role}) Pattern matching (=>) => ӈ୅ೖ(rightw a rd a ssignment) ߏจ ߏ଄Ϛον͠ͳ͍৔߹͸Τϥʔ͕ rise ͞ΕΔ (NoMatchingPatternKeyError ͳͲ)

Slide 69

Slide 69 text

File.read('test.txt') .split("\n") .map(&:strip) .reject(&:empty?) .first(10) => lines [BASE_URL, path].join('/') .then { URI.open(it).read } .then { JSON.parse(it) } .dig('owner' ) .then { it.to_yaml } => yaml => Λ୅ೖ͚ͩͷ༻్Ͱ࢖͏͜ͱ΋ ͜Ε͸࠷ۙ ݟΔؾ͕͢Δ ϨΞϦςΟ௿Ί … ͔΋

Slide 70

Slide 70 text

next

Slide 71

Slide 71 text

user => { name:, age: 13..28} puts %(#{name} is gen-Z) ϨΞϦςΟɿ˒˒˒˒˒˒

Slide 72

Slide 72 text

Pattern matching (Expression) (Ruby 3.1~) ref. Ruby 3.1 ch a nges - Ruby Ch a nges ( https://rubyreferences.github.io/rubych a nges/3.1.html#p a ttern-m a tching ) ref. p a ttern_m a tching - Document a tion for Ruby 3.5 ( https://docs.ruby-l a ng.org/en/m a ster/synt a x/p a ttern_m a tching_rdoc.html )

Slide 73

Slide 73 text

user => { name:, age: 13..28} puts %(#{name} is gen-Z) Pattern Matching(Expressions) ࣜΛ࢖ͬͨύλʔϯϚον ϩʔΧϧม਺Ҏ֎ͷม਺(non-loc a l v a ri a bles) Λࣜ෦ʹ࢖͏৔߹͸ ^ ۟Λ࢖ͬͨ pinning ॲཧ͕ඞཁ (ৄࡉུ) ม਺΁ͷׂΓ౰ͯ͸ߦΘΕͳ͍

Slide 74

Slide 74 text

next

Slide 75

Slide 75 text

case user in role: "admin" puts "super user" in age: 13..28 puts %(#{name} is gen-Z) in name:, role: puts %(#{name} is #{role}) end ϨΞϦςΟɿ˒˒˒˒˒˒˒

Slide 76

Slide 76 text

Pattern matching (case) (Ruby 3.2~) ref. Ruby 3.2 ch a nges - Ruby Ch a nges ( https://rubyreferences.github.io/rubych a nges/3.2.html#p a ttern-m a tching ) ref. p a ttern_m a tching - Document a tion for Ruby 3.5 ( https://docs.ruby-l a ng.org/en/m a ster/synt a x/p a ttern_m a tching_rdoc.html )

Slide 77

Slide 77 text

case user in role: "admin" puts "super user" in age: 13..28 puts %(#{name} is gen-Z) in name:, role: puts %(#{name} is #{role}) end Pattern matching (case) case-when ߏจͱ΄΅ಉ͡

Slide 78

Slide 78 text

• Ruby: "uselessγϯλοΫεγϡΨʔ"γϦʔζʮύλʔϯϚονϯά ʢ1/3ʣʯʢ຋༁ʣʛTechR a cho by BPSגࣜձࣾ • https://techr a cho.bpsinc.jp/h a chi8833/2024_01_31/138590 • ·ͩ·ͩԞਂ͍ • ΫϥεͷҰகνΣοΫͱ͔ • "Find p a ttern" value in [*, pattern, *] ͱ͔ Pattern matching ਂ۷Γ

Slide 79

Slide 79 text

next

Slide 80

Slide 80 text

5.times{|n| p n if (n==2)..(n==3) } ϨΞϦςΟɿ˒˒˒˒˒˒˒˒

Slide 81

Slide 81 text

fl ip- fl op ৚݅ࣜ ref. ԋࢉࢠࣜ (Ruby 3.4 ϦϑΝϨϯεϚχϡΞϧ) ( https://docs.ruby-l a ng.org/j a /l a test/doc/spec=2foper a tor.html#r a nge_cond )

Slide 82

Slide 82 text

5.times{|n| p n if (n==2)..(n==3) } # => 2 # 3 fl ip- fl op ৚݅ࣜ ʮ৚݅ࣜͱͯ͠ʯൣғࣜΛهड़ͨ͠ͱ͖͚ͩͷಛघಈ࡞ "ࠨ෦Λຬͨͨ͠Βɺӈ෦Λຬͨ͢·Ͱ true" "Range ͷதʹऩ·ͬͯͨΒ" Ͱ͸ͳ͍

Slide 83

Slide 83 text

[1,2,3,4,5,4,3,2,1].each{|n| p n if (n==3..) } fl ip- fl op తͳಈ࡞ྫ

Slide 84

Slide 84 text

[1,2,3,4,5,4,3,2,1].each{|n| p n if (n==3..) } # => 3 # 4 # 5 # 4 # 3 # 2 ← でる # 1 ← でる fl ip- fl op తͳಈ࡞ྫ

Slide 85

Slide 85 text

• ʮঢ়ଶʯΛ࣋ͭಛघͳ৚݅ࣜ • ঢ়ଶ = ॳظঢ়ଶ or ࣜ1͕Ϛονͨ͠ޙ or ࣜ2͕Ϛονͨ͠ޙ • .. ͷ৔߹ͱ ... ͷ৔߹Ͱಈ࡞͕एׯҟͳΔ • sed ΍ a wk ༝དྷͷಈ࡞ • ݸਓతʹ͸ɺ࣮ࡍʹ࢖ΘΕ͍ͯΔͱ͜ΖΛݟͨ͜ͱ͕ͳ͍ • ύʔαʔͱ͔Ͱ͔ͭΘΕ͍ͯΔΜͩΖ͏ɺͱࢥ͏ • ಈ࡞Λޡղ͠΍͍ͨ͢Ί͚͞ΒΕ͍ͯΔɺͷ͔΋ fl ip- fl op ਂ۷Γ

Slide 86

Slide 86 text

break

Slide 87

Slide 87 text

Ruby ʹ͸ ͍Ζ͍Ζͳॻ͖ํ͕͋Γ·͢Ͷ

Slide 88

Slide 88 text

શ෦Λ࢖͍͜ͳ͢ඞཁ͸ͳ͍ ಡΊΔͱͪΐͬͱ ࣌ؒͷઅ໿ʹͳΔ͔΋

Slide 89

Slide 89 text

ಡΊͳͯ͘΋ AI ʹฉ͚͹ ͓͓Αͦਖ਼͘͠ղઆͯ͘͠ΕΔ

Slide 90

Slide 90 text

Happy Ruby Coding! Tomokazu Kiyohara http://github.com/kiyohara http://facebook.com/tomokazu.kiyohara