[#88240] [Ruby trunk Feature#14759] [PATCH] set M_ARENA_MAX for glibc malloc — sam.saffron@...
Issue #14759 has been updated by sam.saffron (Sam Saffron).
[#88251] Re: [ruby-alerts:8236] failure alert on trunk@P895 (NG (r64134)) — Eric Wong <normalperson@...>
[email protected] wrote:
[#88305] [Ruby trunk Bug#14968] [PATCH] io.c: make all pipes nonblocking by default — normalperson@...
Issue #14968 has been reported by normalperson (Eric Wong).
[#88331] [Ruby trunk Feature#13618] [PATCH] auto fiber schedule for rb_wait_for_single_fd and rb_waitpid — samuel@...
Issue #13618 has been updated by ioquatix (Samuel Williams).
[#88342] [Ruby trunk Feature#14955] [PATCH] gc.c: use MADV_FREE to release most of the heap page body — ko1@...
Issue #14955 has been updated by ko1 (Koichi Sasada).
[#88433] [Ruby trunk Feature#13618] [PATCH] auto fiber schedule for rb_wait_for_single_fd and rb_waitpid — ko1@...
Issue #13618 has been updated by ko1 (Koichi Sasada).
[email protected] wrote:
[#88475] [Ruby trunk Misc#14937] [PATCH] thread_pthread: lazy-spawn timer-thread only on contention — ko1@...
Issue #14937 has been updated by ko1 (Koichi Sasada).
[#88491] Re: [ruby-cvs:71466] k0kubun:r64374 (trunk): test_function.rb: skip running test — Eric Wong <normalperson@...>
[email protected] wrote:
I see. Please remove the test if the test is unnecessary.
Takashi Kokubun <[email protected]> wrote:
[#88523] [Ruby trunk Bug#14999] ConditionVariable doesn't reacquire the Mutex if Thread#kill-ed — eregontp@...
Issue #14999 has been updated by Eregon (Benoit Daloze).
[email protected] wrote:
[#88549] [Ruby trunk Bug#14999] ConditionVariable doesn't reacquire the Mutex if Thread#kill-ed — eregontp@...
Issue #14999 has been updated by Eregon (Benoit Daloze).
[#88676] [Ruby trunk Misc#15014] thread.c: use rb_hrtime_scalar for high-resolution time operations — ko1@...
Issue #15014 has been updated by ko1 (Koichi Sasada).
[email protected] wrote:
On 2018/08/27 16:16, Eric Wong wrote:
[#88716] Re: [ruby-dev:43715] [Ruby 1.9 - Bug #595] Fiber ignores ensure clause — Eric Wong <normalperson@...>
Koichi Sasada wrote:
[#88723] [Ruby trunk Bug#15041] [PATCH] cont.c: set th->root_fiber to current fiber at fork — ko1@...
Issue #15041 has been updated by ko1 (Koichi Sasada).
[#88767] [Ruby trunk Bug#15050] GC after forking with fibers crashes — ko1@...
Issue #15050 has been updated by ko1 (Koichi Sasada).
Koichi Sasada <[email protected]> wrote:
Koichi Sasada <[email protected]> wrote:
[#88774] Re: [ruby-alerts:8955] failure alert on trunk@P895 (NG (r64594)) — Eric Wong <normalperson@...>
[email protected] wrote:
[ruby-core:88289] [Ruby trunk Feature#14869] Proposal to add Hash#===
Issue #14869 has been updated by baweaver (Brandon Weaver).
I would agree with `===` being more useful than `<=`, as `case`, `all?`, `grep`, and other methods use it implicitly.
This would be an amazing addition for Ruby, and would bring us closer to pattern matching syntax.
The great part about this is your implementation uses `===` to compare values as well. This makes it very flexible, and extremely useful.
**Aside / Offtopic**
This may be unrelated, and if so feel free to tell me to open another issue, but what if it worked on Objects:
```
Person = Struct.new(:id, :name, :age)
people = [{:id=>1, :name=>"Homu", :age=>13}, {:id=>2, :name=>"mami", :age=>14}].map { |p| Person.new(*p.values) }
people.grep(age: 10..13) # => [#<struct Person id=1, name="Homu", age=13>]
```
----------------------------------------
Feature #14869: Proposal to add Hash#===
https://bugs.ruby-lang.org/issues/14869#change-73313
* Author: osyo (manga osyo)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
----------------------------------------
## 概要
`Hash#===` を追加する提案になります。
## 仕様
レシーバのキーの要素と引数のハッシュのキーの要素を `#===` で比較して、全てが真なら `true` を返し、そうでないなら `false` を返す。
また、レシーバが空のハッシュの場合、引数が空のハッシュなら `true` を返し、そうでないなら `false` を返す。
```ruby
user = { id: 1, name: "homu", age: 14 }
# name 要素が data にあるので true
p ({ name: "homu" } === user)
# => true
# 複数の要素があっても OK
p ({ id: 1, name: "homu", age: 14 } === user)
# => true
# name 要素が user にあるが、値が違うので false
p ({ name: "name" } === user)
# => false
# キーの要素が引数にないので false
p ({ number: 42 } === user)
# => false
# 1つでもキーの要素がない場合も false
p ({ id: 1, name: "homu", number: 42 } === user)
# => false
# レシーバが空のハッシュなら false
p ({} == user)
# => false
# 空のハッシュ同士なら true
p ({} == {})
# => true
# 引数がハッシュ以外なら false
p ({ id: 42 } == 42)
# => false
# #=== で比較しているのでこういうこともできる
p ({ name: /^h/ } === user)
# => true
p ({ age: (1..20) } === user)
# => true
p ({ age: Integer } === user)
# => true
```
## ユースケース
### バリデーション
case-when では `===` を使用して値を比較しているので、`Hash#===` を利用することで次のように条件分岐を行うことが出来る。
```ruby
def validation user
case user
# name に対するバリデーション
when { name: /^[a-z]/ }
raise "名前の先頭が小文字の場合は登録できません"
# age に対するバリデーション
when { age: (0..20) }
raise "0〜20歳は登録できません"
# 各要素が任意のクラスのインスタンスかどうかのバリデーション
when { id: Integer, name: String, age: Integer }
true
else
false
end
end
# 条件を満たしているので OK
mami = { id: 1, name: "Mami", age: 21 }
validation mami
# => true
# name が小文字から始まっているので NG
mado = { id: 2, name: "mado", age: 13 }
validation mado
# => 名前の先頭が小文字の場合は登録できません (RuntimeError)
# age が 0〜20歳以内なので NG
homu = { id: 3, name: "Homu", age: 14 }
validation homu
# => 0〜20歳は登録できません (RuntimeError)
```
### `Enumerable#grep`
`Enumerable#grep` は内部で `===` を使用した比較を行っているので、次のように任意の Hash のキーの要素に対して検索を行うことが出来る。
```ruby
data = [
{ id: 1, name: "Homu", age: 13 },
{ id: 2, name: "mami", age: 14 },
{ id: 3, name: "Mado", age: 21 },
{ id: 4, name: "saya", age: 14 },
]
# 特定の要素が含まれている Hash のみを絞り込む
p data.grep(name: /m/)
# => [{:id=>1, :name=>"Homu", :age=>13}, {:id=>2, :name=>"mami", :age=>14}]
p data.grep(age: (1..20))
# => [{:id=>1, :name=>"Homu", :age=>13}, {:id=>2, :name=>"mami", :age=>14}, {:id=>4, :name=>"saya", :age=>14}]
```
## 補足1: `==` ではなくて `===` で比較する理由
* `===` を使用することでより細かい・抽象的な条件を指定することが出来る
* `Class` や `Regexp`、`Proc` などで比較することが出来る
* 内部で `===` を使用している場合、 `==` で比較したい場合は `obj.method(:==)` を渡せば実現出来るが、その逆は出来ない
* 内部で `==` を使用している場合、 `===` で比較ししたくても出来ない
## 補足2: 空のハッシュの比較に関して
* `Object#===` の場合だと `{} === 42` が例外ではなくて `false` を返していたので、`Hash#===` も `false` を返すようにした
* `{} === {}` が `true` を返すのも同様の理由になります
* これにより以下のような既存のコードも互換性を壊すことなく動作するかと思います
```ruby
def check n
case n
when {}
"Empty Hash"
when []
"Empty Array"
when 0
"Zero"
else
"Not empty"
end
end
p check({}) # => "Empty Hash"
p check([]) # => "Empty Array"
p check(0) # => "Zero"
p check({ name: "mado" }) # => "Not empty"
```
以上、`Hash#===` に関する提案になります。
挙動に関して疑問点や意見などございましたらコメント頂けると助かります。
---Files--------------------------------
hash_eqq.patch (3.54 KB)
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>