2021/04/18 今週の気になった bugs.ruby のチケット

内容は適当です。
今週と言っても今週みかけたチケットなだけでチケット自体は昔からあるやつもあります。
あくまでも『わたしが気になったチケット』で全ての bugs.ruby のチケットを載せているわけではありません。

[Feature #17790] Have a way to clear a String without resetting its capacity

  • 文字列の中身を空にする String#clear メソッドがある
str = "abc"
str.clear
p str     # => ""
  • この String#clear メソッドは capacity を含めて解放する
require "objspace"

str = String.new("homuhomu", capacity: 1024)
puts ObjectSpace.dump(str)
# => {"address":"0x55d9bdae3e80", "type":"STRING", "class":"0x55d9bd96a888", "bytesize":8, "capacity":1024, "value":"homuhomu", "encoding":"UTF-8", "memsize":1065, "flags":{"wb_protected":true}}

# clear 後は capacity も含めて解放されている
str.clear
puts ObjectSpace.dump(str)
# => {"address":"0x55d9bdae3e80", "type":"STRING", "class":"0x55d9bd96a888", "embedded":true, "bytesize":0, "value":"", "encoding":"UTF-8", "memsize":40, "flags":{"wb_protected":true}}
  • これは例えば次のように同じバッファを使い回す時に解放されないほうがよいケースもある
buffer = String.new(encoding: Encoding::BINARY, capacity: 1024)

10.times do
  build_next_packet(buffer)
  udp_socket.send(buffer)
  buffer.clear
end
  • なので clear では capacity を開放しないようにする、という提案
  • 議論が進んでいて clear(shrink: true/false) みたいに clear 時に制御するのがいいんじゃない?みたいなコメントもでてる

[Feature #17785] Allow named parameters to be keywords

  • 次のようにキーワード引数に『言語のキーワード』を指定すると参照するのが難しい
def check(arg, class:)
  # ここで class 引数を使いたいが class はキーワードなので参照できない
  arg.is_a?(class)
end

check(42, class: Integer) # => true
  • これを キーワード_ という名前で変数参照できるようにしよう、という提案
def check(arg, class:)
  # _ を付けて参照できるようにする
  arg.is_a?(class_)
end

check(42, class: Integer) # => true
def check(arg, class:)
  # local_variable_get で動的に変数を取得する
  class_ = binding.local_variable_get(:class)
  arg.is_a?(binding.local_variable_get(:class))
end

check(42, class: Integer) # => true
def check(arg, class:)
  arg.is_a?(\class)
end

# キーワード引数以外も適用可能
def diff(start, \end)
  \end - start
end

[Feature #17786] Proposal: new "ends" keyword

  • 複数の endends という1つのキーワードで定義できるようにしようという提案
def render(scene, image, screenWidth, screenHeight)
  screenHeight.times do |y|
    screenWidth.times do |x|
      color = self.traceRay(....)
      r, g, b = Color.toDrawingColor(color)
      image.set(x, y, StumpyCore::RGBA.from_rgb(r, g, b))
    end
  end
end
  • これを以下のように記述する
def render(scene, image, screenWidth, screenHeight)
  screenHeight.times do |y|
    screenWidth.times do |x|
      color = self.traceRay(....)
      r, g, b = Color.toDrawingColor(color)
      image.set(x, y, StumpyCore::RGBA.from_rgb(r, g, b))
ends
  • いろいろとコメントされているが流石に否定的な内容が目立つ…
  • 例えば次のように途中に ends がある場合に class Aend が不用意に閉じられて SyntaxError になる
class A
  def b
    c do
      d do
        e
  ends     # ここで class A のスコープが閉じられる

  def c
  end
end        # なのでここで SyntaxError になる