2021/04/22 今週の気になった bugs.ruby のチケット
内容は適当です。
今週と言っても今週みかけたチケットなだけでチケット自体は昔からあるやつもあります。
あくまでも『わたしが気になったチケット』で全ての bugs.ruby のチケットを載せているわけではありません。
[Bug #9542] Delegator does not delegate protected methods
- 以下のコードが Ruby 2.0 と 2.1 で差異がある、というバグ報告
require "delegate" class Cow def unprotected_moo "mooooo!" end protected def protected_moo "guarded mooooo!" end end my_cow = Cow.new puts SimpleDelegator.new(my_cow).unprotected_moo # => "mooooo!" # protected_moo は protected なのに呼び出すことができる puts SimpleDelegator.new(my_cow).protected_moo # 2.0 => "guarded mooooo!" # 2.1 以降 => undefined method `protected_moo' (NoMethodError) puts my_cow.unprotected_moo # => "mooooo!" puts my_cow.protected_moo # 2.0 => "guarded mooooo!" # 2.1 以降 => protected method `protected_moo' called (NoMethodError)
- これ自体は期待する挙動なので Reject されている
- そもそもチケット自体が7年前のやつだった
[Bug #17814] inconsistent Array.zip behavior
- 以下のように
Array#zip
だとイテレーションが1回余計に呼ばれているというバグ報告
i = 0 # 1 ずつ増えるカウンタ e = Enumerator.produce { i += 1 } # 1つ余計にイテレーションが発生する p [0, 0, 0, 0].zip e # => [[0, 1], [0, 2], [0, 3], [0, 4]] p i # => 5 # Enumerable#zip だと再現しない p [0, 0, 0, 0].each.zip e # => [[0, 6], [0, 7], [0, 8], [0, 9]] p i # => 9
Enumerable#zip
だと問題ないので対応する場合はこっちを使うとよさそう- これは最新版では修正済み
[Feature #17785] Allow named parameters to be keywords
- 先週も書いてた
キーワード_
という名前で変数参照できるようにしよう、という提案
def check(arg, class:) # _ を付けて参照できるようにする arg.is_a?(class_) end check(42, class: Integer) # => true
__params__
みたいな値で受け取れるようにしようという提案があってこれは普通にほしいと思った
def check(arg, class:) arg.is_a?(__params__[:class]) end check(42, class: Integer) # => true
- ただし、キーワード引数以外の引数をどうするかの課題がある
__params__
というよりかは__keyword_params__
みたいな?
[Feature #17718] a method paramaters object that can be pattern matched against
- 次のようにキーワード引数を一括で返すメソッドを追加する提案
- パターンマッチで利用することを想定している
def get_perdiem(city: nil, state: nil, zip:nil) case parameters_match # (return an object of the parameters we can pattern match on) in {zip: zip} find_perdiem_by_zip(zip) in {state: s, city: c} find_perdiem_by_state_and_city(s, c) in { state: s} find_perdiem_by_state(s) else raise 'need combination of zip, city,state' end end
- これは普通にやりたいユースケースだと思う
getParam(**args)
で代替できるとコメントされている
def getParam(**args) case args in {zip: zip} p "zip" in {state: s, city: c} p "state+city" in { state: s} p "state" else raise 'need combination of zip, city, state' end end
- ただし、
**args
だとget_perdiem(nation: "usa")
がArgumentError
にならない問題はある - 要するに [Feature #17785]の
__params__
みたいなのがほしい!!! - なんか引数情報をメタ的に取得する機能がほしいなあ
[Bug #4443] odd evaluation order in a multiple assignment
- 以下のように多重代入した時に先に右辺のメソッドが呼び出されるというバグ報告
- Ruby は左から右に評価が進むので多重代入でもこれを期待する
- https://redmine.ruby-lang.org/issues/4440#note-1
def foo p :foo [] end def bar p :bar end # bar -> foo という順に評価される x, foo[0] = bar, 0 # output: # :bar # :foo # これは foo -> bar という順になる foo[0] = bar # output: # :foo # :bar
- 10年前のチケットで最近修正された
- 最新版だと以下のような動作になる
def foo p :foo [] end def bar p :bar end # 最新版だと foo -> bar と評価されるようになった x, foo[0] = bar, 0 # output: # :foo # :bar
[Feature #17398] SyntaxError in endless method
- 以下のようにエンドレスメソッド定義の本体が statement だった場合にエラーになる、というチケット
# OK def foo() = puts("bar") # syntax error, unexpected string literal, expecting `do' or '{' or '(' def hoge() = puts "bar"
- いくつか問題点があるが修正する方針で進めているらしい
- 現状提案されているパッチだと以下のような挙動になる
# current: SyntaxError # patch: Allow def foo() = puts "bar" # current: SyntaxError # patch: SyntaxError private def foo() = puts "bar"
[Feature #15198] Array#intersect?
Array#intersect?
を追加する提案- これは以下の動作と同じ意味
Array#&
[1, 1, 2, 3] & [3, 1, 4] #=> [1, 3]
(a1 & a2).any?