[#107430] [Ruby master Feature#18566] Merge `io-wait` gem into core IO — "byroot (Jean Boussier)" <noreply@...>

Issue #18566 has been reported by byroot (Jean Boussier).

22 messages 2022/02/02

[#107434] [Ruby master Bug#18567] Depending on default gems when not needed considered harmful — "Eregon (Benoit Daloze)" <noreply@...>

Issue #18567 has been reported by Eregon (Benoit Daloze).

31 messages 2022/02/02

[#107443] [Ruby master Feature#18568] Explore lazy RubyGems boot to reduce need for --disable-gems — "headius (Charles Nutter)" <noreply@...>

Issue #18568 has been reported by headius (Charles Nutter).

13 messages 2022/02/02

[#107481] [Ruby master Feature#18571] Removed the bundled sources from release package after Ruby 3.2 — "hsbt (Hiroshi SHIBATA)" <noreply@...>

Issue #18571 has been reported by hsbt (Hiroshi SHIBATA).

9 messages 2022/02/04

[#107490] [Ruby master Bug#18572] Performance regression when invoking refined methods — "palkan (Vladimir Dementyev)" <noreply@...>

Issue #18572 has been reported by palkan (Vladimir Dementyev).

12 messages 2022/02/05

[#107514] [Ruby master Feature#18576] Rename `ASCII-8BIT` encoding to `BINARY` — "byroot (Jean Boussier)" <noreply@...>

Issue #18576 has been reported by byroot (Jean Boussier).

47 messages 2022/02/08

[#107536] [Ruby master Feature#18579] Concatenation of ASCII-8BIT strings shouldn't behave differently depending on string contents — "tenderlovemaking (Aaron Patterson)" <noreply@...>

Issue #18579 has been reported by tenderlovemaking (Aaron Patterson).

11 messages 2022/02/09

[#107547] [Ruby master Bug#18580] Range#include? inconsistency for String ranges — "zverok (Victor Shepelev)" <noreply@...>

Issue #18580 has been reported by zverok (Victor Shepelev).

10 messages 2022/02/10

[#107603] [Ruby master Feature#18589] Finer-grained constant invalidation — "kddeisz (Kevin Newton)" <noreply@...>

Issue #18589 has been reported by kddeisz (Kevin Newton).

17 messages 2022/02/16

[#107624] [Ruby master Bug#18590] String#downcase and CAPITAL LETTER I WITH DOT ABOVE — "andrykonchin (Andrew Konchin)" <noreply@...>

Issue #18590 has been reported by andrykonchin (Andrew Konchin).

13 messages 2022/02/17

[#107651] [Ruby master Misc#18591] DevMeeting-2022-03-17 — "mame (Yusuke Endoh)" <noreply@...>

Issue #18591 has been reported by mame (Yusuke Endoh).

11 messages 2022/02/18

[#107682] [Ruby master Feature#18595] Alias `String#-@` as `String#dedup` — "byroot (Jean Boussier)" <noreply@...>

Issue #18595 has been reported by byroot (Jean Boussier).

15 messages 2022/02/21

[#107699] [Ruby master Feature#18597] Strings need a named method like `dup` that doesn't duplicate if receiver is mutable — "danh337 (Dan H)" <noreply@...>

Issue #18597 has been reported by danh337 (Dan H).

18 messages 2022/02/21

[ruby-core:107633] [Ruby master Feature#18498] Introduce a public WeakKeysMap that compares by equality

From: "matz (Yukihiro Matsumoto)" <noreply@...>
Date: 2022-02-17 13:17:00 UTC
List: ruby-core #107633
Issue #18498 has been updated by matz (Yukihiro Matsumoto).


I agree with introducing a map (hash) with each key referenced weakly.  It should be in the core since weak references should be tightly integrated with the garbage collector. 

Since the current `WeakMap` is hard to implement in JRuby, I also agree with making the existing `WeakMap` obsolete (gradually). 

We need to determine the detail:

* **Where to place the class**: we have several options. I vote for putting it under `ObjectSpace` as the current `WeakMap`
* **The name of the class**: OP proposed `WeakKeysMap`. I prefer `WeakKeyMap` probably because my native language (Japanese) does not have noun plurality. But considering the class is "a map with each key referenced weakly", still `WeakKeyMap` looks better to me.
* **Behavior**: we should start with minimal set of methods. How about:
  * `ObjectSpace::WeakKeyMap#[](key)`
  * `ObjectSpace::WeakKeyMap#[]=(key, val)`
  * `ObjectSpace::WeakKeyMap#getkey(key)`
  * `ObjectSpace::WeakKeyMap#inspect #=> #<ObjectSpace::WeakKeyMap size=100>`

Matz.


----------------------------------------
Feature #18498: Introduce a public WeakKeysMap that compares by equality
https://bugs.ruby-lang.org/issues/18498#change-96544

* 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>

In This Thread