2020/11/19 今週の気になった bugs.ruby のチケット
内容は適当です。
今週と言っても今週みかけたチケットなだけでチケット自体は昔からあるやつもあります。
あくまでも『わたしが気になったチケット』で全ての bugs.ruby のチケットを載せているわけではありません。
[Feature #17330] Object#non
Object#non
を追加する提案Object#non
の実装は以下の通り
class Object # ブロックの戻り値が偽ならレシーバを返し、そうでないなら nil を返す def non self unless yield(self) end end # 0 じゃない場合はレシーバを返す p 1.non { _1.zero? } # => 1 p 0.non { _1.zero? } # => nil # 空じゃない場合はレシーバを返す p [1, 2, 3].non { _1.empty? } # => [1, 2, 3] p [].non { _1.empty? } # => nil
- チケットにはいくつかユースケースが載ってるので初回
limit = calculate.some.limit # limit が 0 の場合は DEFAULT_LIMIT を返し、そうでない場合は limit を返す limit.zero? ? DEFAULT_LIMIT : limit # もしくは nonzero? メソッドを使う # これは 0 であれば nil を返し、そうでなければレシーバを返す calculate.some.limit.nonzero? || DEFAULT_LIMIT # #non を使うとこんな感じ calculate.some.limit.non(&:zero?) || DEFAULT_LIMIT # ^ Note here, how, unlike `nonzero?`, we see predicate-y ?, but it is INSIDE the `non()` and less confusing
# params[:name] があり空でない場合は name に代入する name = params[:name] if params[:name] && !params[:name].empty? # ActiveSupport だと presence が使える name = params[:name].presence # #non を使うとこんな感じ name = params[:name]&.non(&:empty?)
- 最近ほしいと思った書き方
# ARGV が空の場合はデフォルト値を設定する argv = ARGV.non(&:empty?) || ["--hoge"]
- かなり便利そうなので標準にほしい…
[Feature #17333] Enumerable#many?
Enumerable#many?
を追加する提案- ActiveSupport には同名のメソッドが定義されていて『条件にマッチする要素が 2個以上の場合』に
true
を返す
[1, 2, 3].many?(&:odd?) # は以下と同じ意味 [1, 2, 3].count(&:odd?) > 1
- ActiveSupport で定義されているもののユースケースがパッと思いつかなかった
- 欲しい人はコメントしてアピールするといいと思います!
[Bug #17332] No error when using endless method definitions with self.
setters
- Ruby 3.0 preview1 では
=
がついてる endless method は定義できない
p RUBY_DESCRIPTION # => "ruby 3.0.0preview1 (2020-09-25 master 0096d2b895) [x86_64-linux]" # error: setter method cannot be defined in an endless method definition def value=() = 42
- しかし、preview1 ではクラスメソッドで
=
がついてるメソッドが定義できてしまうというバグ報告
p RUBY_DESCRIPTION # => "ruby 3.0.0preview1 (2020-09-25 master 0096d2b895) [x86_64-linux]" # OK def value=() = 42
- この挙動は開発版の Ruby ではすでに修正済みとなっている
p RUBY_DESCRIPTION # => "ruby 3.0.0dev (2020-11-11T09:11:09Z master fa3670e6e4) [x86_64-linux]" # error: setter method cannot be defined in an endless method definition def self.value=() = 42
[Bug #11213] defined?(super) ignores respond_to_missing?
defined?(super)
した時に#respond_to_missing?
が反映されない?というバグ報告- 5年前のチケット
class C0 def method_missing(*args) [:method_missing, *args] end def respond_to_missing?(*args) true end end class C1 < C0 def foo # suepr を呼び出すことはできるが p super # => [:method_missing, :foo] # respond_to_missing? は呼ばれずに defined? は nil を返す p defined?(super) # => nil end end c1 = C1.new c1.foo
- 最近
#respond_to_missing?
を呼び出すような修正 PR が投げられてて気づいた
[Feature #17328] Extend un.rb
to be usable by everyone
$ ruby -run -e cp -- [-prv] SOURCE DEST $ ruby -run -e ln -- [-sfv] TARGET LINK_NAME $ ruby -run -e mv -- [-v] SOURCE DEST $ ruby -run -e rm -- [-frv] FILE $ ruby -run -e mkdir -- [-pv] DIRS $ ruby -run -e rmdir -- [-v] DIRS $ ruby -run -e install -- [-pv -m mode] SOURCE DEST $ ruby -run -e chmod -- [-v] OCTAL-MODE FILE $ ruby -run -e touch -- [-v] FILE $ ruby -run -e wait_writable -- [OPTION] FILE $ ruby -run -e mkmf -- [OPTION] EXTNAME [OPTION] $ ruby -run -e httpd -- [OPTION] [DocumentRoot] $ ruby -run -e help [COMMAND]
- これは
-r
でun
をrequre "un"
して-e
でcp
メソッドを呼び出している、というような挙動になる - この
require "un"
した時に暗黙的にrun.rb
も読み込もうという提案になる - 例えば以下のように
rub.rb
を定義しておくと
def greet puts 'Hello!' end
ruby -run -e greet
のようにメソッドを呼び出すことができる- 便利そうだが、これは
ruby run.rb -e greet
すればいいだけなのでこの提案は Reject されている