22. 変形ルールをプログラムで書く
22
S
x
y
z
x z y z
def ski(e)
if e[0] == :I
e[1]
elsif e[0][0] == :K
e[0][1]
elsif e[0][0][0]==:S
[[e[0][0][1], # x
e[1]], # z
[e[0][1], # y
e[1]]] # z
else
...
end
end
[[[:S, x], y], z] [[x,z], [y,z]]
26. 変形ルールをパターンマッチで書く
26
S
x
y
z
x z y z
def ski(e)
case e
in [:I, x]
x
in [[:K, x], y]
x
in [[[:S,x],y],z]
[[x,z],[y,z]]
else
...
end
end[[[:S, x], y], z] [[x,z], [y,z]]
34. …非互換!
• 意図的に混同してたコードがRuby 3で動かない
34
def foo(**opt)
...
end
h = {x: 43}
foo(h)
def foo(opt={})
...
end
foo(x: 43)
このケースは
Ruby 3でも
許すことになった
これは
許さない
と書き直してね
foo(**h)
35. Ruby 2.7は移行支援バージョン
• 基本的にはRuby 2.6と同じ意味
• しかし3.0で変わる挙動に警告を出す
• www.ruby-lang.orgに移行ガイドを掲載する予定です
35
def foo(a,b,c,opt: 42)
end
foo(1, 2, opt:43)
#=> -:3: warning: The keyword argument is passed as the last hash parameter
# -:1: warning: for `foo' defined here
36. 委譲の新記法: (...)
• 委譲:引数をすべて別メソッドに横流しすること
36
def bar(a, b, c)
end
def foo(...)
bar(...)
end
foo(1, 2, 3)
def foo(*args, &blk)
bar(*args, &blk)
end
Ruby 2でまじめに書く場合
def foo(*args, **opts, &blk)
bar(*args, **opts, &blk)
end
Ruby 3でまじめに書く場合
37. トラップ:(...) はカッコが必須
• 「Rubyはカッコが省略できていいよね~」
• Ruby 2.7では行末に…があったら警告が出ます
37
def foo(...)
bar ...
end
残念!endless range
と解釈されます
(bar...)
def foo(...)
bar ...
end
#=> -:2: warning: ... at EOL, should be parenthesized?