2022/04/21 今回の気になった bugs.ruby のチケット
今週はレシーバに対して Kernel#p
が呼び出せるようにする提案がありました。
[Feature #18736] self-p for method chain
- 次のようにメソッドチェーンの間にレシーバを出力したいという要望チケット
class Object def sp(method=nil, *args, &block) if method Kernel.p self.public_send(method, *args, &block) elsif block_given? Kernel.p block.call(self) else Kernel.p self end return self end end # sp のレシーバを標準出力する p [1,2,3].map{|x| x**2}.sp.map{|x| x**2} # output: # [1, 4, 9] # [1, 16, 81] # ブロックの結果を出力する [1,2,3].sp{|x| "my List = #{x}"} # output: # "my List = [1, 2, 3]" # レシーバに対して sum(-10) を呼び出した結果を出力する [1,2,3].sp(:sum,-10) # output: # -4
#tap
すると以下のように書くことができる
# sp のレシーバを標準出力する p [1,2,3].map{|x| x**2}.tap(&method(:p)).map{|x| x**2} # output: # [1, 4, 9] # [1, 16, 81] # ブロックの結果を出力する [1,2,3].tap{|x| p "my List = #{x}"} # output: # "my List = [1, 2, 3]" # レシーバに対して sum(-10) を呼び出した結果を出力する [1,2,3].tap { p _1.sum(-10) } # output: # -4
- 別チケットだと以下のようなのが提案されている
- これ系のメソッドはめっちゃほしいんだよなあ…
[Bug #18729] Method#owner and UnboundMethod#owner are incorrect after using Module#public/protected/private
- 次のように
public / protected / private
を呼び出した後に#owner
が変わってないというバグ報告
class A protected def foo :A end end class B < A p [instance_method(:foo), instance_method(:foo).owner, instance_methods(false), A.instance_methods(false)] public :foo p [instance_method(:foo), instance_method(:foo).owner, instance_methods(false), A.instance_methods(false)] end # outptu: # [#<UnboundMethod: B(A)#foo() owner.rb:2>, A, [], [:foo]] # [#<UnboundMethod: B(A)#foo() owner.rb:2>, A, [:foo], [:foo]]
B
でfoo
が再定義されているのにowner
がB(A)#foo()
のままになっている- 期待する挙動は以下の通り
[#<UnboundMethod: B(A)#foo() owner.rb:2>, A, [], [:foo]] [#<UnboundMethod: B#foo() owner.rb:2>, B, [:foo], [:foo]]
[Bug #18741] Slicing an Array using index out of range inconsistent return type
- 範囲外の値を
Array#[]
に渡したときの挙動が一貫していないというバグ報告
def test_slicing_arrays array = [:peanut, :butter, :and, :jelly] assert_equal [:peanut], array[0,1] assert_equal [:peanut, :butter], array[0,2] assert_equal [:and, :jelly], array[2,2] assert_equal [:and, :jelly], array[2,20] assert_equal [], array[4,0] # 範囲外を指定した時にこっちは [] を返す assert_equal [], array[4,100] assert_equal nil, array[5,0] # 同様に範囲外を指定しているがこっちは nil を返す end
- これは [Feature #16822] Array slicing: nils and edge cases と似たようなチケットでこちらは Reject されている
[Feature #18742] Introduce a way to tell if a method invokes the super
keyword
- メソッド内で
super
を呼び出しているかどうかを判定するメソッドを追加する提案
class X def a end; p instance_method(:a).calls_super? #=> false def b super end; p instance_method(:b).calls_super? #=> true def c super if false end; p instance_method(:c).calls_super? #=> true def d eval 'super' end; p instance_method(:d).calls_super? #=> false (I doubt there's a reasonable way for this to return true) end
- https://bugs.ruby-lang.org/issues/18618#note-1 の実装をする時に利用できると書いてある
- ユースケースがかなりエッジケースだけど他に利用できる箇所とかあるかなあ