NEWS for Ruby 2.7.0

[edit]

このドキュメントは前回リリース以降のバグ修正を除くユーザーに影響のある機能の変更のリストです。

それぞれのエントリーは参照情報があるため短いです。十分な情報と共に書かれた全ての変更のリストは ChangeLog ファイルか bugs.ruby-lang.org の issue を参照してください。

2.6.0 以降の変更

言語仕様の変更

パターンマッチ


case [0, [1, 2, 3]]
in [a, [b, *c]]
  p a #=> 0
  p b #=> 1
  p c #=> [2, 3]
end

case {a: 0, b: 1}
in {a: 0, x: 1}
  :unreachable
in {a: 0, b: var}
  p var #=> 1
end

case -1
in 0 then :unreachable
in 1 then :unreachable
end #=> NoMatchingPatternError
json = <<END
{
  "name": "Alice",
  "age": 30,
  "children": [{ "name": "Bob", "age": 2 }]
}
END

JSON.parse(json, symbolize_names: true) in {name: "Alice", children: [{name: name, age: age}]}

p name #=> "Bob"
p age  #=> 2

JSON.parse(json, symbolize_names: true) in {name: "Alice", children: [{name: "Charlie", age: age}]}
#=> NoMatchingPatternError

3.0 に向けてのキーワード引数の仕様変更


def foo(key: 42); end; foo({key: 42})   # warned
def foo(**kw);    end; foo({key: 42})   # warned
def foo(key: 42); end; foo(**{key: 42}) # OK
def foo(**kw);    end; foo(**{key: 42}) # OK

def foo(h, **kw); end; foo(key: 42)      # warned
def foo(h, key: 42); end; foo(key: 42)   # warned
def foo(h, **kw); end; foo({key: 42})    # OK
def foo(h, key: 42); end; foo({key: 42}) # OK

def foo(h={}, key: 42); end; foo("key" => 43, key: 42)   # warned
def foo(h={}, key: 42); end; foo({"key" => 43, key: 42}) # warned
def foo(h={}, key: 42); end; foo({"key" => 43}, key: 42) # OK

def foo(opt={});  end; foo( key: 42 )   # OK

def foo(**kw); p kw; end; foo("str" => 1) #=> {"str"=>1}

def foo(h, **nil); end; foo(key: 1)       # ArgumentError
def foo(h, **nil); end; foo(**{key: 1})   # ArgumentError
def foo(h, **nil); end; foo("str" => 1)   # ArgumentError
def foo(h, **nil); end; foo({key: 1})     # OK
def foo(h, **nil); end; foo({"str" => 1}) # OK

h = {}; def foo(*a) a end; foo(**h) # []
h = {}; def foo(a) a end; foo(**h)  # {} and warning
h = {}; def foo(*a) a end; foo(h)   # [{}]
h = {}; def foo(a) a end; foo(h)    # {}

番号指定パラメータ


[1, 2, 10].map { _1.to_s(16) }    #=> ["1", "2", "a"]
[[1, 2], [3, 4]].map { _1 + _2 }  #=> [3, 7]
_1 = 0            #=> warning: `_1' is reserved for numbered parameter; consider another name
[1].each { p _1 } # prints 0 instead of 1

ブロックなしの proc/lambda が deprecated


def foo
  proc
end
foo { puts "Hello" } #=> warning: Capturing the given block using Kernel#proc is deprecated; use `&block` instead

def bar
  lambda
end
bar { puts "Hello" } #=> tried to create Proc object without a block (ArgumentError)

その他の変更


ary[..3]  # identical to ary[0..3]

case RUBY_VERSION
when ..."2.4" then puts "EOL"
# ...
end

age.clamp(..100)

where(sales: ..100)
<<"EOS
" # This had been warned since 2.4; Now it raises a SyntaxError
EOS

foo
  # .bar
  .baz # => foo.baz

a, b = raise rescue [1, 2]
# Previously parsed as: (a, b = raise) rescue [1, 2]
# Now parsed as:         a, b = (raise rescue [1, 2])
def foo
  class << Object.new
    yield #=> warning: `yield' in class syntax will not be supported from Ruby 3.0. [[feature:15575]]
  end
end
foo { p :ok }

def foo(...)
  bar(...)
end

コマンドラインオプション

警告オプション

カテゴリ化された警告を管理するために「-W」オプションが「:」を続けられるように拡張されました。 [feature#16345] [feature#16420]

$ ruby -e '$; = ""'
-e:1: warning: `$;' is deprecated

$ ruby -W:no-deprecated -e '$; = //'
$ RUBYOPT=-W:no-deprecated ruby -e '$; = //'
$ ruby -e '0 in a'
-e:1: warning: Pattern matching is experimental, and the behavior may change in future versions of Ruby!

$ ruby -W:no-experimental -e '0 in a'
$ RUBYOPT='-W:no-deprecated -W:no-experimental' ruby -e '($; = "") in a'

組み込みクラスの更新のWarningも参照してください。

組み込みクラスの更新 (注目すべきもののみ)


-1.clamp(0..2) #=> 0
 1.clamp(0..2) #=> 1
 3.clamp(0..2) #=> 2
# With beginless and endless ranges:
-1.clamp(0..)  #=> 0
 3.clamp(..2)  #=> 2
Enumerable#filter_map

[1, 2, 3].filter_map {|x| x.odd? ? x.to_s : nil } #=> ["1", "3"]
Enumerable#tally

["A", "B", "C", "B", "A"].tally #=> {"A"=>2, "B"=>2, "C"=>1}
Enumerator.produce

require "date"
dates = Enumerator.produce(Date.today, &:succ) #=> infinite sequence of dates
dates.detect(&:tuesday?) #=> next Tuesday
Enumerator::Lazy#eager

a = %w(foo bar baz)
e = a.lazy.map {|x| x.upcase }.map {|x| x + "!" }.eager
p e.class               #=> Enumerator
p e.map {|x| x + "?" }  #=> ["FOO!?", "BAR!?", "BAZ!?"]
Enumerator::Lazy#with_index

("a"..).lazy.with_index(1) { |it, index| puts "#{index}:#{it}" }.take(3).force
# => 1:a
#    2:b
#    3:c

File.extname("foo.") #=> "."

0b01001101[2, 4]  #=> 0b0011
0b01001100[2..5]  #=> 0b0011
0b01001100[2...6] #=> 0b0011
#   ^^^^

class Foo
  def add_1(x)
    x + 1
  end
end
class Bar < Foo
  def add_1(x) # override
    x + 2
  end
end

obj = Bar.new
p obj.add_1(1) #=> 3
p Foo.instance_method(:add_1).bind(obj).call(1) #=> 2
p Foo.instance_method(:add_1).bind_call(obj, 1) #=> 2

標準添付ライブラリの更新 (注目すべきもののみ)

test.rb

require "optparse"
OptionParser.new do |opts|
  opts.on("-f", "--foo", "foo") {|v| }
  opts.on("-b", "--bar", "bar") {|v| }
  opts.on("-c", "--baz", "baz") {|v| }
end.parse!
$ ruby test.rb --baa
Traceback (most recent call last):
test.rb:7:in `<main>': invalid option: --baa (OptionParser::InvalidOption)
Did you mean?  baz
               bar

互換性 (機能追加とバグ修正を除く)

標準添付ライブラリの互換性 (機能追加とバグ修正を除く)

C API の更新

実装の改善

$ ./configure --with-coroutine=ucontext
$ ./configure --with-coroutine=copy

その他の変更