ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses
@ 2021-10-27 13:27 byroot (Jean Boussier)
  2021-10-28 11:31 ` [ruby-core:105849] [Ruby master Feature#18273] Class#subclasses Eregon (Benoit Daloze)
                   ` (33 more replies)
  0 siblings, 34 replies; 35+ messages in thread
From: byroot (Jean Boussier) @ 2021-10-27 13:27 UTC (permalink / raw
  To: ruby-core

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

----------------------------------------
Feature #18273: Class.subclasses
https://bugs.ruby-lang.org/issues/18273

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:105849] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
@ 2021-10-28 11:31 ` Eregon (Benoit Daloze)
  2021-10-28 12:10 ` [ruby-core:105852] " byroot (Jean Boussier)
                   ` (32 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Eregon (Benoit Daloze) @ 2021-10-28 11:31 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by Eregon (Benoit Daloze).


+1 for Class#subclasses, I think it makes sense since we have Class#descendants.

`Class#subclasses` is then also the "complement" of `Class#superclass`,
just like `Class#descendants` is the complement of `Class#ancestors`.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-94388

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:105852] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
  2021-10-28 11:31 ` [ruby-core:105849] [Ruby master Feature#18273] Class#subclasses Eregon (Benoit Daloze)
@ 2021-10-28 12:10 ` byroot (Jean Boussier)
  2021-11-16  7:41 ` [ruby-core:106079] " mame (Yusuke Endoh)
                   ` (31 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: byroot (Jean Boussier) @ 2021-10-28 12:10 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by byroot (Jean Boussier).


I took a stab at it: https://github.com/ruby/ruby/pull/5045

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-94391

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:106079] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
  2021-10-28 11:31 ` [ruby-core:105849] [Ruby master Feature#18273] Class#subclasses Eregon (Benoit Daloze)
  2021-10-28 12:10 ` [ruby-core:105852] " byroot (Jean Boussier)
@ 2021-11-16  7:41 ` mame (Yusuke Endoh)
  2021-11-16  8:49 ` [ruby-core:106080] " byroot (Jean Boussier)
                   ` (30 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: mame (Yusuke Endoh) @ 2021-11-16  7:41 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by mame (Yusuke Endoh).


I am afraid if the name "subclasses" is suitable. When we have three classes `C`, `D` that inherits from `C`, and `E` that inherits from `D`, we say "E is a subclass of C".

In fact, the rdoc of `Module#<` says

> mod < other → true, false, or nil
>
> Returns true if mod is a subclass of other.

and `E < C` returns true.

```
class C; end
class D < C; end
class E < D; end

p E < C #=> true
```

So, `Class#subclasses` sounds the same as `Class#descendants`.

If we take family line as an analogy, `Class#children` might be good. @ko1 suggested `Class#direct_subclasses`.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-94668

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:106080] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (2 preceding siblings ...)
  2021-11-16  7:41 ` [ruby-core:106079] " mame (Yusuke Endoh)
@ 2021-11-16  8:49 ` byroot (Jean Boussier)
  2021-11-16  8:55 ` [ruby-core:106082] " sawa (Tsuyoshi Sawada)
                   ` (29 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: byroot (Jean Boussier) @ 2021-11-16  8:49 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by byroot (Jean Boussier).


Fine by me, we'll have to go through a deprecation period in Rails but that's not a big deal.

What about it being a boolean parameter on `descendants` ? Was this option considered ? 

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-94669

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:106082] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (3 preceding siblings ...)
  2021-11-16  8:49 ` [ruby-core:106080] " byroot (Jean Boussier)
@ 2021-11-16  8:55 ` sawa (Tsuyoshi Sawada)
  2021-11-16  9:02 ` [ruby-core:106083] " mame (Yusuke Endoh)
                   ` (28 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: sawa (Tsuyoshi Sawada) @ 2021-11-16  8:55 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by sawa (Tsuyoshi Sawada).


I agree with mame, which brings in another question: Was the method name `Class#superclass` appropriate? Perhaps this method should also be renamed, say, to `Class#parent`.

An alternative is to allow an optional keyword `direct` (or `immediate`) on both `Class#ancestors` and `Class#descendants`. 

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-94671

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:106083] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (4 preceding siblings ...)
  2021-11-16  8:55 ` [ruby-core:106082] " sawa (Tsuyoshi Sawada)
@ 2021-11-16  9:02 ` mame (Yusuke Endoh)
  2021-11-16  9:07 ` [ruby-core:106084] " mame (Yusuke Endoh)
                   ` (27 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: mame (Yusuke Endoh) @ 2021-11-16  9:02 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by mame (Yusuke Endoh).


byroot (Jean Boussier) wrote in #note-6:
> What about it being a boolean parameter on `descendants` ? Was this option considered ?

`descendants(immediate = false)` looks reasonable to me. A keyword argument might be preferable to an optional argument.

sawa (Tsuyoshi Sawada) wrote in #note-7:
> Was the method name `Class#superclass` appropriate?

I think we don't say "C is a superclass of E" in the same situation, but I'm unsure.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-94672

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:106084] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (5 preceding siblings ...)
  2021-11-16  9:02 ` [ruby-core:106083] " mame (Yusuke Endoh)
@ 2021-11-16  9:07 ` mame (Yusuke Endoh)
  2021-11-16 12:24 ` [ruby-core:106086] " Eregon (Benoit Daloze)
                   ` (26 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: mame (Yusuke Endoh) @ 2021-11-16  9:07 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by mame (Yusuke Endoh).


mame (Yusuke Endoh) wrote in #note-8:
> sawa (Tsuyoshi Sawada) wrote in #note-7:
> > Was the method name `Class#superclass` appropriate?
> 
> I think we don't say "C is a superclass of E" in the same situation, but I'm unsure.

Ah, I misunderstood. I have no idea whether an alias `Class#parent` is needed.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-94673

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:106086] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (6 preceding siblings ...)
  2021-11-16  9:07 ` [ruby-core:106084] " mame (Yusuke Endoh)
@ 2021-11-16 12:24 ` Eregon (Benoit Daloze)
  2021-11-17  1:47 ` [ruby-core:106102] " sawa (Tsuyoshi Sawada)
                   ` (25 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: Eregon (Benoit Daloze) @ 2021-11-16 12:24 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by Eregon (Benoit Daloze).


AFAIK superclass is always understand as the direct superclass.
And given we already have Class#descendants and Module#ancestors, I feel there is very little room for confusion for Class#subclasses (i.e., almost no confusion possible).
Of course we can document it clearly in that method's documentation it's only "classes which have C has the superclass", and link to `Class#descendants`.

IMHO `Class#direct_subclasses` is verbose and not helpful.
Rails already established that `subclasses` is a clear meaning for this.

Regarding a boolean argument for `Class#descendants` I'm neutral, I think that's less good and one definitely need to read the docs just to find the meaning of the boolean, plus they might not guess it even takes an argument.
`Class#subclasses` is clearer and is already an established name for this.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-94677

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:106102] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (7 preceding siblings ...)
  2021-11-16 12:24 ` [ruby-core:106086] " Eregon (Benoit Daloze)
@ 2021-11-17  1:47 ` sawa (Tsuyoshi Sawada)
  2021-11-18  6:13 ` [ruby-core:106116] " matz (Yukihiro Matsumoto)
                   ` (24 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: sawa (Tsuyoshi Sawada) @ 2021-11-17  1:47 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by sawa (Tsuyoshi Sawada).


mame (Yusuke Endoh) wrote in #note-8:
> I think we don't say "C is a superclass of E" in the same situation, but I'm unsure.

If there is any sense in understanding the word "superclass" to mean only the direct ancestor, that is because it is in singular form, not because the word per se implies directness. The singular form leads a programmer to infer that it must mean something unique, hence the direct ancestor, excluding the indirect ones. The word itself does not imply directness. In fact, there are some definitions out there that explicitly mention indirect ancestors to be included in "superclass": https://www.whitman.edu/mathematics/java_tutorial/java/javaOO/subclasses.html

> The term superclass refers to a class's direct ancestor as well as all of its ascendant classes.

When it comes to subclass, even the direct ones are not unique, which means that directness cannot be distinguished by referring to singularity, and it is this fact that is making it clearer that the word does not imply directness.

So my suggestion is that, as pointed out by mame, avoid the method name "subclasses", and deprecate "superclass" in favor of something else.

From compatibility and uniformity with other methods involving (in)directness such as `Module#instance_methods`, I now think it is a good idea to make the directness parameter to be positional, with truthy value meaning "including indirect", and falsy meaning "only direct", default being truthy.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-94691

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:106116] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (8 preceding siblings ...)
  2021-11-17  1:47 ` [ruby-core:106102] " sawa (Tsuyoshi Sawada)
@ 2021-11-18  6:13 ` matz (Yukihiro Matsumoto)
  2022-01-24  0:15 ` [ruby-core:107245] " fxn (Xavier Noria)
                   ` (23 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: matz (Yukihiro Matsumoto) @ 2021-11-18  6:13 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by matz (Yukihiro Matsumoto).


`Class#subclasses` sounds OK.  Accepted.

Matz.


----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-94713

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107245] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (9 preceding siblings ...)
  2021-11-18  6:13 ` [ruby-core:106116] " matz (Yukihiro Matsumoto)
@ 2022-01-24  0:15 ` fxn (Xavier Noria)
  2022-01-24  0:32 ` [ruby-core:107246] " fxn (Xavier Noria)
                   ` (22 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: fxn (Xavier Noria) @ 2022-01-24  0:15 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by fxn (Xavier Noria).


In my view, this method does not play well with object lifetime, semantically.

Take for example:

```ruby
C = Class.new
-> { Class.new(C); 1 }.call
pp C.subclasses # => [#<Class:0x000000010c8f5a90>]
```

On line 3, the subclass of `C` does not exist anymore conceptually, but `Class#subclasses` depends on GC actually deleting the object. That is non-deterministic behaviour.

This affects reloading in Zeitwerk, which is implemented via `remove_const`. If the program using Zeitwerk is correct, after `remove_const` there are no strong references to the unloaded object. But if you define a subclass again on reload, `C#subclasses` may yield two objects instead of one.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96106

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107246] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (10 preceding siblings ...)
  2022-01-24  0:15 ` [ruby-core:107245] " fxn (Xavier Noria)
@ 2022-01-24  0:32 ` fxn (Xavier Noria)
  2022-01-24  8:26 ` [ruby-core:107247] " byroot (Jean Boussier)
                   ` (21 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: fxn (Xavier Noria) @ 2022-01-24  0:32 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by fxn (Xavier Noria).


Said in a different way:

```ruby
C = Class.new
-> { Class.new(C); 1 }.call
pp C.subclasses
pp C.subclasses
```

If GC kicks in between lines 3 and 4, you may get different results. In my opinion, this non-determinism is not good for an API like this one.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96107

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107247] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (11 preceding siblings ...)
  2022-01-24  0:32 ` [ruby-core:107246] " fxn (Xavier Noria)
@ 2022-01-24  8:26 ` byroot (Jean Boussier)
  2022-01-24 10:01 ` [ruby-core:107248] " fxn (Xavier Noria)
                   ` (20 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: byroot (Jean Boussier) @ 2022-01-24  8:26 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by byroot (Jean Boussier).


> In my view, this method does not play well with object lifetime, semantically.

This is perfectly fine, Ruby isn't concerned about wether a `Class` is still present in the constant table or not (or if it ever was). That's also how the old Active Support implementation based on `ObjectSpace.each_object` behaved.

That's why [`DescendantTracker` keeps a `WeakMap` of the unregistered classes to give the illusion in reload mode](https://github.com/rails/rails/blob/9062d705ad9055c0f3ec73505150e0e94fff5925/activesupport/lib/active_support/descendants_tracker.rb#L26).

> If GC kicks in between lines 3 and 4, you may get different results. In my opinion, this non-determinism is not good for an API like this one.

That too was considered and is fine.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96108

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107248] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (12 preceding siblings ...)
  2022-01-24  8:26 ` [ruby-core:107247] " byroot (Jean Boussier)
@ 2022-01-24 10:01 ` fxn (Xavier Noria)
  2022-01-24 10:07 ` [ruby-core:107249] " byroot (Jean Boussier)
                   ` (19 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: fxn (Xavier Noria) @ 2022-01-24 10:01 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by fxn (Xavier Noria).


> This is perfectly fine, Ruby isn't concerned about wether a Class is still present in the constant table or not

I am talking about object lifetimes, my example does not store the class object in a constant.

In my view, this API is not consistent with the Ruby model. In the Ruby model, you have class objects, and they have superclasses. Instances hold a strong reference to their classes.

Whether you store those objects in variables or constants, or not at all (as in the example above), is orthogonal to that model.

So, in this model, `Class#subclasses` cannot be deterministic.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96109

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107249] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (13 preceding siblings ...)
  2022-01-24 10:01 ` [ruby-core:107248] " fxn (Xavier Noria)
@ 2022-01-24 10:07 ` byroot (Jean Boussier)
  2022-01-24 10:13 ` [ruby-core:107250] " fxn (Xavier Noria)
                   ` (18 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: byroot (Jean Boussier) @ 2022-01-24 10:07 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by byroot (Jean Boussier).


I don't think I understand what your issue is. `subclasses` returns all the *live object* (not yet GCed) that are direct descendants.

In *my* Ruby model it works as expected.

Do you mean that in your Ruby model, objects are "gced" as soon as they are unreachable? How do weakref / weakmap work in your model then?



----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96110

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107250] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (14 preceding siblings ...)
  2022-01-24 10:07 ` [ruby-core:107249] " byroot (Jean Boussier)
@ 2022-01-24 10:13 ` fxn (Xavier Noria)
  2022-01-24 10:17 ` [ruby-core:107251] " byroot (Jean Boussier)
                   ` (17 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: fxn (Xavier Noria) @ 2022-01-24 10:13 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by fxn (Xavier Noria).


What I mean is that `Class#subclasses` is effectively a cache that does not have proper invalidation.

The red flag for me is the example above, in a linear program:

```ruby
C.subclasses
C.subclasses
```

should return the same. It does not, so in my view this cache is not good enough to be in the language itself.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96111

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107251] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (15 preceding siblings ...)
  2022-01-24 10:13 ` [ruby-core:107250] " fxn (Xavier Noria)
@ 2022-01-24 10:17 ` byroot (Jean Boussier)
  2022-01-24 10:18 ` [ruby-core:107252] " fxn (Xavier Noria)
                   ` (16 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: byroot (Jean Boussier) @ 2022-01-24 10:17 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by byroot (Jean Boussier).


To me it behave just like weak references do:

```ruby
weakmap = ObjectSpace::WeakMap.new
weakmap[Object.new] = Object.new
weakmap.keys # => [#<Object:0x00007ff6329049c8>]
# GC.start
weakmap.keys # => []
```

I really see no problem with that.



----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96112

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107252] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (16 preceding siblings ...)
  2022-01-24 10:17 ` [ruby-core:107251] " byroot (Jean Boussier)
@ 2022-01-24 10:18 ` fxn (Xavier Noria)
  2022-01-24 10:20 ` [ruby-core:107253] " byroot (Jean Boussier)
                   ` (15 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: fxn (Xavier Noria) @ 2022-01-24 10:18 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by fxn (Xavier Noria).


That is, _since_ objects are not gced as soon as they are unreachable, this implementation of `Class#subclasses` is non-deterministic, and therefore not good enough to be in the language itself. That is my point of view :).

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96113

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107253] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (17 preceding siblings ...)
  2022-01-24 10:18 ` [ruby-core:107252] " fxn (Xavier Noria)
@ 2022-01-24 10:20 ` byroot (Jean Boussier)
  2022-01-24 10:28 ` [ruby-core:107254] " fxn (Xavier Noria)
                   ` (14 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: byroot (Jean Boussier) @ 2022-01-24 10:20 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by byroot (Jean Boussier).


Sure, and you are entitled to it, I just don't understand how you reconcile it with the existence of weak references.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96114

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107254] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (18 preceding siblings ...)
  2022-01-24 10:20 ` [ruby-core:107253] " byroot (Jean Boussier)
@ 2022-01-24 10:28 ` fxn (Xavier Noria)
  2022-01-24 10:31 ` [ruby-core:107255] " fxn (Xavier Noria)
                   ` (13 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: fxn (Xavier Noria) @ 2022-01-24 10:28 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by fxn (Xavier Noria).


> Sure, and you are entitled to it, I just don't understand how you reconcile it with the existence of weak references.

I believe our legitimate differences in view points are:

1. You say it works as expected, based on weak refs.
2. I say, true, but a posteriori, usage is not deterministic for the user, and therefore not a good core API.

The documentation should say: Returns the subclasses that have not been yet GCed. Multiple calls may yield different values even if you don't touch the hierarchy in between them.

To me, having to write such documentation is a suggesting this feature is dubious.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96115

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107255] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (19 preceding siblings ...)
  2022-01-24 10:28 ` [ruby-core:107254] " fxn (Xavier Noria)
@ 2022-01-24 10:31 ` fxn (Xavier Noria)
  2022-01-24 10:38 ` [ruby-core:107256] " zverok (Victor Shepelev)
                   ` (12 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: fxn (Xavier Noria) @ 2022-01-24 10:31 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by fxn (Xavier Noria).


To me, this feature makes sense in a language where subclasses cannot disappear once created. In Ruby, they are regular objects. This is the root mismatch between the core language and this API.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96116

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107256] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (20 preceding siblings ...)
  2022-01-24 10:31 ` [ruby-core:107255] " fxn (Xavier Noria)
@ 2022-01-24 10:38 ` zverok (Victor Shepelev)
  2022-01-24 11:19 ` [ruby-core:107257] " fxn (Xavier Noria)
                   ` (11 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: zverok (Victor Shepelev) @ 2022-01-24 10:38 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by zverok (Victor Shepelev).


@fxn Isn't it an inherent property of a dynamic language, that whatever you can introspect about the code structure, can change in runtime? So the methods truthfully reflecting the current state of the structure are perfectly sane? 

I'd argue it is not a qualitative difference from a change of the `subclasses` because something was _defined_ in runtime. I can see how it can be said to be different (because in the case of subclass vanishing, nothing on user level of the program can be pointed as a code that led to the change), but is this difference practicalor only affects "theoretical clarity"?

I assume that as a developer of the Zeitwerk you maybe can provide some insight on practical consequences?

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96117

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107257] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (21 preceding siblings ...)
  2022-01-24 10:38 ` [ruby-core:107256] " zverok (Victor Shepelev)
@ 2022-01-24 11:19 ` fxn (Xavier Noria)
  2022-01-24 12:19 ` [ruby-core:107258] " fxn (Xavier Noria)
                   ` (10 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: fxn (Xavier Noria) @ 2022-01-24 11:19 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by fxn (Xavier Noria).


@zverok Absolutely, the API of a dynamic language should be dynamic.

For example, take this:

```ruby
C = Class.new
Object.subclasses # (1)

D = Class.new
Object.subclasses # (2)
```

For the user, it makes sense that (1) includes `C`, and (2) includes `C` and `D`. They are guaranteed to be there, because `Object` has a strong reference to them via its constants table, and this fact belongs to the public API of Ruby. (My points are not about constants, but in that example, in order to say that (2) has `C` and `D` I need to say there's a strong reference somewhere.)

If you later on add a mixin:

```ruby
C.include(M)
```

of course, `C.ancestors` is supposed to reflect that change.

What would be strange is that

```ruby
C.ancestors
C.ancestors
```

could yield different results if you did not change the ancestor chain in between.

That is, you didn't do anything to change that collection.

> but is this difference practicalor only affects "theoretical clarity"

It's not marble tower theoretical clarity, it is just that the API of the language has to agree with the language model.

There are APIs that conceptually are about live objects, like `ObjectSpace`. But `Class#subclasses` is not at that level, conceptually. `Class#subclasses` is at the level of `Module#ancestors`, in my view.

> I assume that as a developer of the Zeitwerk you maybe can provide some insight on practical consequences?

In my view, the API introduces a broken window, a method that behaves in a non-deterministic way. Broken windows leak.



----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96118

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107258] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (22 preceding siblings ...)
  2022-01-24 11:19 ` [ruby-core:107257] " fxn (Xavier Noria)
@ 2022-01-24 12:19 ` fxn (Xavier Noria)
  2022-01-24 13:26 ` [ruby-core:107259] " zverok (Victor Shepelev)
                   ` (9 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: fxn (Xavier Noria) @ 2022-01-24 12:19 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by fxn (Xavier Noria).


Hmm, now that I think, maybe you don't see how this affects Zeitwerk directly.

In Zeitwerk, "reloading" means issuing `remove_const` calls to unload, and execute `Module#autoload` calls to be reading to load again fresh definitions. So, in a reload something like this happens:

```ruby
C = Class.new

D = Class.new(C)

# Reload.
Object.send(:remove_const, D)
D = Class.new(C)

C.subclasses # => [D, D]
```

In which situation would you find that? Well, in any situation where `Class#subclasses` is used in the context of reloading.

However, I add this comment to further clarify that specific question about Zeitwerk.

My remarks are not about Zeitwerk, they are more fundamental, at the language/core API level.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96119

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107259] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (23 preceding siblings ...)
  2022-01-24 12:19 ` [ruby-core:107258] " fxn (Xavier Noria)
@ 2022-01-24 13:26 ` zverok (Victor Shepelev)
  2022-01-24 13:38 ` [ruby-core:107260] " fxn (Xavier Noria)
                   ` (8 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: zverok (Victor Shepelev) @ 2022-01-24 13:26 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by zverok (Victor Shepelev).


TBH, I still fail to see the point of how the API clearly reflecting the reality should be considered a "broken window". 

Two subsequent calls returning different results without user's code affecting these results is not that uncommon: if you'll try to introspect the current state/list of threads, or fibers, or ractors; if you try to look at files and directories while something else changed them; well, if you just `Time.now` two times in a row...

From my perspective (being obsessed with docs and teaching people) it is rather fortunate that with `Class#subclasses` we'll have a clear and obvious place to write: yes, subclasses may vanish, please beware and remember; it is an important thing to say explicitly!

I don't think "that would be strange" is a strong enough argument here, if it clearly reflects *what's really going on*.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96120

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107260] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (24 preceding siblings ...)
  2022-01-24 13:26 ` [ruby-core:107259] " zverok (Victor Shepelev)
@ 2022-01-24 13:38 ` fxn (Xavier Noria)
  2022-01-24 13:48 ` [ruby-core:107261] " zverok (Victor Shepelev)
                   ` (7 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: fxn (Xavier Noria) @ 2022-01-24 13:38 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by fxn (Xavier Noria).


@zverok one thing is "subclasses can vanish", because the language is dynamic (like ancestors can change), and a different thing is that in this program:

```ruby
Class.new
Object.subclasses
```

you cannot tell me what is the 2 line going to return.

Personally, I find this non-deterministic behavior unacceptable for an API of this level.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96121

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107261] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (25 preceding siblings ...)
  2022-01-24 13:38 ` [ruby-core:107260] " fxn (Xavier Noria)
@ 2022-01-24 13:48 ` zverok (Victor Shepelev)
  2022-01-24 13:55 ` [ruby-core:107262] " fxn (Xavier Noria)
                   ` (6 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: zverok (Victor Shepelev) @ 2022-01-24 13:48 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by zverok (Victor Shepelev).


We are going in circles here :( It is "non-deterministic" all right, but also reflects the reality.

It is more or less the same as with
```ruby
Thread.new {}.run
Thread.list
```
...isn't it? We can't predict what the 2nd line is going to return. 

Should we argue that `Time.now` value can't be predicted and therefore non-deterministic, and therefore a bad API?

(I am not trolling, I am trying to see what lies in the gap between just repeating that it is non-deterministic and therefore not acceptable from one side, and it is how it really is and therefore totally sane API from another.)

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96122

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107262] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (26 preceding siblings ...)
  2022-01-24 13:48 ` [ruby-core:107261] " zverok (Victor Shepelev)
@ 2022-01-24 13:55 ` fxn (Xavier Noria)
  2022-01-24 14:11 ` [ruby-core:107263] " fxn (Xavier Noria)
                   ` (5 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: fxn (Xavier Noria) @ 2022-01-24 13:55 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by fxn (Xavier Noria).


@zverok sure!

I see your point, it works as it is supposed to be.

My point is, `Class#subclasses` should be deterministic like `Module#ancestors`. In the sense that, as a programmer, if I do not change the collection, it should stay the same.

Since that is not possible (at least in this implementation), in my logic, that means `Class#subclasses` should not be added to Ruby.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96123

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107263] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (27 preceding siblings ...)
  2022-01-24 13:55 ` [ruby-core:107262] " fxn (Xavier Noria)
@ 2022-01-24 14:11 ` fxn (Xavier Noria)
  2022-01-24 14:52 ` [ruby-core:107265] " zverok (Victor Shepelev)
                   ` (4 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: fxn (Xavier Noria) @ 2022-01-24 14:11 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by fxn (Xavier Noria).


> In the sense that, as a programmer, if I do not change the collection, it should stay the same.

Of course, removing a subclass is ill-defined and that is the root problem I see here. And in Ruby that makes sense, because the link only went upwards only.

On the other hand, `Module#ancestors` can be a linearized cache because there is no API or way to remove ancestors.

Ruby doesn't have API/semantics to provide a similar `Class#subclasses`.

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96124

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107265] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (28 preceding siblings ...)
  2022-01-24 14:11 ` [ruby-core:107263] " fxn (Xavier Noria)
@ 2022-01-24 14:52 ` zverok (Victor Shepelev)
  2022-01-24 14:52 ` [ruby-core:107266] " fxn (Xavier Noria)
                   ` (3 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: zverok (Victor Shepelev) @ 2022-01-24 14:52 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by zverok (Victor Shepelev).


@fxn You know what? 

I think I actually got your point:
* `Class#ancestors` represent a "really existing thing", that is, objective ancestors chain. E.g. it is an API to an internal _structures_, helping to make sense of them;
* `Class#subclasses` look the same way, therefore implying it is also an API to internally existing structures (for example, to each class keeping track of its descendants because it is a part of an object model)—but this implication is completely untrue! The `#subclasses` is a dynamic thing—and in more formal language, maybe should've at least been called `#enumerate_subclasses` (implying by a verb form that it will _do_  something, not just expose internally existing reality)

Is that it?

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96125

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107266] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (29 preceding siblings ...)
  2022-01-24 14:52 ` [ruby-core:107265] " zverok (Victor Shepelev)
@ 2022-01-24 14:52 ` fxn (Xavier Noria)
  2022-01-24 14:53 ` [ruby-core:107267] " fxn (Xavier Noria)
                   ` (2 subsequent siblings)
  33 siblings, 0 replies; 35+ messages in thread
From: fxn (Xavier Noria) @ 2022-01-24 14:52 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by fxn (Xavier Noria).


@zverok I think our disagreement is clear. Perhaps your position is also the one of @byroot.

To me, `Class#subclasses` cannot be defined because in Ruby there's no such concept as "removing a subclass". And this is an API for which I would expect determinism.

Of course, `Time.now` or `ObjectSpace` are different kinds of APIs.

I believe we'll need to agree on disagreeing :).

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96126

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107267] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (30 preceding siblings ...)
  2022-01-24 14:52 ` [ruby-core:107266] " fxn (Xavier Noria)
@ 2022-01-24 14:53 ` fxn (Xavier Noria)
  2022-01-24 15:45 ` [ruby-core:107268] " fxn (Xavier Noria)
  2022-01-24 22:40 ` [ruby-core:107271] " zverok (Victor Shepelev)
  33 siblings, 0 replies; 35+ messages in thread
From: fxn (Xavier Noria) @ 2022-01-24 14:53 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by fxn (Xavier Noria).


@zverok Sorry, we were typing at the same time.

Exactly! That is my point of view!

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96127

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107268] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (31 preceding siblings ...)
  2022-01-24 14:53 ` [ruby-core:107267] " fxn (Xavier Noria)
@ 2022-01-24 15:45 ` fxn (Xavier Noria)
  2022-01-24 22:40 ` [ruby-core:107271] " zverok (Victor Shepelev)
  33 siblings, 0 replies; 35+ messages in thread
From: fxn (Xavier Noria) @ 2022-01-24 15:45 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by fxn (Xavier Noria).


More than the existence of a real collection (which is a private implementation detail), it is the existence of a **clear collection API** .

In ancestors, you have API for adding, and no API for removing or updating in-place. So, the programmer can always know what is `Module#ancestors` just by looking at the code.

Ruby has API for subclassing. And you have strong pointer from class to superclass, that is all. That is your you got.

So, the concept of "subclasses" at any given point is fuzzy, because the virtual collection of subclasses is ill-defined.

This cache is therefore using the only tool it has at hand, alive objects and garbage collection. But to me, the resulting semantics are as fuzzy in consequence, for something that shouldn't be, in my opinion.

Look at the docs, you have the happy path using constants. These docs should be more complete, warning the user, and introducing garbage collection in their description. At this point, you (generic you :) may agree the existence of these docs indicates the method should not exist.



----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96128

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [ruby-core:107271] [Ruby master Feature#18273] Class#subclasses
  2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
                   ` (32 preceding siblings ...)
  2022-01-24 15:45 ` [ruby-core:107268] " fxn (Xavier Noria)
@ 2022-01-24 22:40 ` zverok (Victor Shepelev)
  33 siblings, 0 replies; 35+ messages in thread
From: zverok (Victor Shepelev) @ 2022-01-24 22:40 UTC (permalink / raw
  To: ruby-core

Issue #18273 has been updated by zverok (Victor Shepelev).


I see, and tend to agree—to some extent, at least!

Not sure how much can be done here—some amount of "semantically not really clear, yet convenient" methods trickle from Rails/ActiveSupport. (My personal "favorite" is Array#intersect and related methods, making Array API pretending it is set instead of enhancing Set and making it more popular.)

I could at least do this: https://github.com/ruby/ruby/pull/5480, WDYT?

----------------------------------------
Feature #18273: Class#subclasses
https://bugs.ruby-lang.org/issues/18273#change-96131

* Author: byroot (Jean Boussier)
* Status: Closed
* Priority: Normal
----------------------------------------
Ref: https://github.com/rails/rails/pull/43481

Something we forgot to mention in [Feature #14394], is either a parameter or another method to only get direct descendants.

Active Support has been offering `Class.subclasses` as:

```ruby
  def subclasses
    descendants.select { |descendant| descendant.superclass == self }
  end
```

It seems a bit silly to grab all descendants and then restrict the list when `Class#descendants` had to do some recursion to get them all in the first place.

### Proposal

We could either implement `Class#subclasses` directly, or accept a parameter in `Class#descendants`, e.g. `descendants(immediate = false)`.

cc @eregon



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2022-01-24 22:40 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-10-27 13:27 [ruby-core:105826] [Ruby master Feature#18273] Class.subclasses byroot (Jean Boussier)
2021-10-28 11:31 ` [ruby-core:105849] [Ruby master Feature#18273] Class#subclasses Eregon (Benoit Daloze)
2021-10-28 12:10 ` [ruby-core:105852] " byroot (Jean Boussier)
2021-11-16  7:41 ` [ruby-core:106079] " mame (Yusuke Endoh)
2021-11-16  8:49 ` [ruby-core:106080] " byroot (Jean Boussier)
2021-11-16  8:55 ` [ruby-core:106082] " sawa (Tsuyoshi Sawada)
2021-11-16  9:02 ` [ruby-core:106083] " mame (Yusuke Endoh)
2021-11-16  9:07 ` [ruby-core:106084] " mame (Yusuke Endoh)
2021-11-16 12:24 ` [ruby-core:106086] " Eregon (Benoit Daloze)
2021-11-17  1:47 ` [ruby-core:106102] " sawa (Tsuyoshi Sawada)
2021-11-18  6:13 ` [ruby-core:106116] " matz (Yukihiro Matsumoto)
2022-01-24  0:15 ` [ruby-core:107245] " fxn (Xavier Noria)
2022-01-24  0:32 ` [ruby-core:107246] " fxn (Xavier Noria)
2022-01-24  8:26 ` [ruby-core:107247] " byroot (Jean Boussier)
2022-01-24 10:01 ` [ruby-core:107248] " fxn (Xavier Noria)
2022-01-24 10:07 ` [ruby-core:107249] " byroot (Jean Boussier)
2022-01-24 10:13 ` [ruby-core:107250] " fxn (Xavier Noria)
2022-01-24 10:17 ` [ruby-core:107251] " byroot (Jean Boussier)
2022-01-24 10:18 ` [ruby-core:107252] " fxn (Xavier Noria)
2022-01-24 10:20 ` [ruby-core:107253] " byroot (Jean Boussier)
2022-01-24 10:28 ` [ruby-core:107254] " fxn (Xavier Noria)
2022-01-24 10:31 ` [ruby-core:107255] " fxn (Xavier Noria)
2022-01-24 10:38 ` [ruby-core:107256] " zverok (Victor Shepelev)
2022-01-24 11:19 ` [ruby-core:107257] " fxn (Xavier Noria)
2022-01-24 12:19 ` [ruby-core:107258] " fxn (Xavier Noria)
2022-01-24 13:26 ` [ruby-core:107259] " zverok (Victor Shepelev)
2022-01-24 13:38 ` [ruby-core:107260] " fxn (Xavier Noria)
2022-01-24 13:48 ` [ruby-core:107261] " zverok (Victor Shepelev)
2022-01-24 13:55 ` [ruby-core:107262] " fxn (Xavier Noria)
2022-01-24 14:11 ` [ruby-core:107263] " fxn (Xavier Noria)
2022-01-24 14:52 ` [ruby-core:107265] " zverok (Victor Shepelev)
2022-01-24 14:52 ` [ruby-core:107266] " fxn (Xavier Noria)
2022-01-24 14:53 ` [ruby-core:107267] " fxn (Xavier Noria)
2022-01-24 15:45 ` [ruby-core:107268] " fxn (Xavier Noria)
2022-01-24 22:40 ` [ruby-core:107271] " zverok (Victor Shepelev)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).