[#107008] [Ruby master Bug#18465] Make `IO#write` atomic. — "ioquatix (Samuel Williams)" <noreply@...>
Issue #18465 has been reported by ioquatix (Samuel Williams).
16 messages
2022/01/09
[#107150] [Ruby master Feature#18494] [RFC] ENV["RUBY_GC_..."]= changes GC parameters dynamically — "ko1 (Koichi Sasada)" <noreply@...>
Issue #18494 has been updated by ko1 (Koichi Sasada).
4 messages
2022/01/17
[#107170] Re: [Ruby master Feature#18494] [RFC] ENV["RUBY_GC_..."]= changes GC parameters dynamically
— Eric Wong <normalperson@...>
2022/01/17
> https://bugs.ruby-lang.org/issues/18494
[#107302] [Ruby master Bug#18553] Memory leak on compiling method call with kwargs — "ibylich (Ilya Bylich)" <noreply@...>
Issue #18553 has been reported by ibylich (Ilya Bylich).
4 messages
2022/01/27
[#107346] [Ruby master Misc#18557] DevMeeting-2022-02-17 — "mame (Yusuke Endoh)" <noreply@...>
Issue #18557 has been reported by mame (Yusuke Endoh).
18 messages
2022/01/29
[ruby-core:107197] [Ruby master Feature#18498] Introduce a public WeakKeysMap that compares by equality
From:
"Eregon (Benoit Daloze)" <noreply@...>
Date:
2022-01-19 17:41:03 UTC
List:
ruby-core #107197
Issue #18498 has been updated by Eregon (Benoit Daloze).
This looks great to me.
I prefer `WeakKeysMap`. `WeakRef::WeakKeysMap` sounds fine too.
Anything with `Hash` in the name is IMHO not great because Hash implies ordering and Map no ordering, per well-established concurrent-ruby classes (Concurrent::Hash and Concurrent::Map).
Having `WeakKeys` in the name seems best/useful, as there might be a `WeakValuesMap` in the future.
I believe `WeakKeysMap#dedup` should be a core method (i.e., predefined on WeakKeysMap), that way it can be guaranteed thread-safe on all Ruby implementations with minimal overhead.
Doing it manually with Mutex when defined in Ruby would have a significant overhead.
ObjectSpace::WeakMap is already thread-safe on CRuby, JRuby and TruffleRuby so it only makes sense WeakKeysMap is thread-safe as well.
`WeakKeysMap#dedup` also makes that use-case much easier as the user does not need to define `dedup` themselves.
I would prefer no `compare_by_identity` support for simplicity.
If `compare_by_identity` is included, such choice should be made when creating the WeakKeysMap (e.g. `WeakKeysMap.new(compare_by_identity: true)`), not later as that causes a whole lot of mess implementation-wise and makes the semantics unclear.
----------------------------------------
Feature #18498: Introduce a public WeakKeysMap that compares by equality
https://bugs.ruby-lang.org/issues/18498#change-96060
* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
This is a clean take on #16038
### Spec
#### Weak keys only
After a chat with @eregon we believe that what would make the most sense and would be most useful would be
a "WeakKeysMap". Meaning **the keys would be weak references, but the values would be strong references**.
This behavior is also consistent with the terminology in other popular languages such as Javascript and Java were `WeakMap` only have weak keys.
By default **it would use equality semantic, just like a regular `Hash`**. Having an option to compare by indentity instead
could be useful, but not strictly required.
#### Immediate objects support
Many WeakMap implementation in other languages don't accept "immediate" objects (or their equivalent) in the weak slots.
This is because since they are never collected, the weak reference will never possibly expire.
`ObjectSpace::WeakMap` currently accept them, but since both keys and values are weak references, there is legitimate use.
However in a `WeakKeysMap`, using an immediate object as key should likely raise a `TypeError`.
What is less clear is wether `BIGNUM` (allocated `Integer`) and dynamic symbols (allocated `Symbol`) should be accepted.
I believe they shouldn't for consistency, so:
- No immediate objects
- No `Integer`
- No `Symbol`
#### `member` method to lookup an existing key
For some use case, notably deduplication sets, a `member` method that maps `st_get_key` would be useful.
```ruby
def member(key) -> existing key or nil
```
Not sure if `member` is the best possible name, but `#key` is already used for looking up a key by value.
That same method could be useful on `Hash` and `Set` as well, but that would be a distinct feature request.
#### Naming
Possible names:
- `::WeakMap`
- `::WeakKeysMap`
- `::WeakRef::Map`
- `::WeakRef::WeakMap`
- `::WeakRef::WeakKeysMap`
- `::WeakRef::WeakHash`
- `::WeakRef::WeakKeysHash`
My personal, ligthly held, preference goes toward `::WeakRef::WeakKeysMap`.
### Use cases
#### WeakSet
A `WeakKeysMap` would be a good enough primitive to implement a `WeakSet` in pure Ruby code, just like `Set` is
implemented with a `Hash`.
`WeakSet` are useful for use cases such as avoiding cycles in an object graph without holding strong references.
#### Deduplication sets
Assuming `WeakMap` have the `#member` method.
A small variation on the "deduplicating constructors" use case, better suited for smaller but numerous objects.
The difference here is that we first build the object and then lookup for a pre-existing one. This is the
strategy used to [deduplicate Active Record schema metadata](https://github.com/rails/rails/blob/3be590edbedab8ddcacdf72790d50c3cf9354434/activerecord/lib/active_record/connection_adapters/deduplicable.rb#L5).
```ruby
class DeduplicationSet
def initialize
@set = WeakKeysMap.new
end
def dedup(object)
if existing_object = @set.member(object)
existing_object
else
@set[object] = true
object
end
end
end
```
#### Third party object extension
When you need to record some associated data on third party objects for which you don't control the lifetime.
A WeakMap can be used:
```ruby
METADATA = WeakKeysMap.new
def do_something(third_party_object)
metadata = (METADATA[third_party_object] ||= Metadata.new)
metadata.foo = "bar"
end
```
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>