From: "Dan0042 (Daniel DeLorme) via ruby-core" <ruby-core@...>
Date: 2023-06-19T17:46:55+00:00
Subject: [ruby-core:113946] [Ruby master Feature#19521] Support for `Module#name=` and `Class#name=`.

Issue #19521 has been updated by Dan0042 (Daniel DeLorme).


> However, this will prevent `labeled_class`/`labeled_module` from using `set_temporary_name`, at least until those labels are updated to be "not a constant name" or we remove this restriction. When I did this change, ~35 tests failed. I don't know if all my use cases will be satisfied, so I can try to introduce this limitation, and if I'm satisfied, I can leave it. Otherwise, I might revisit it if such a restriction turns out to be an issue.

Ah interesting, I didn't realize it was already used that way. Since the ruby main repo already demonstrates how to "lie" about the class name in a sensible and useful way, I believe this is perfectly fine.

> Ruby is a dynamic language, and this is a consequence of such dynamic behaviour which cannot, realistically, be completely prevented.

FWIW, I 100% agree. As Matz himself [said](https://bugs.ruby-lang.org/issues/15723#note-2):
> The **possibility** to make code cryptic itself should not be the reason to withdraw a feature.


----------------------------------------
Feature #19521: Support for `Module#name=` and `Class#name=`.
https://bugs.ruby-lang.org/issues/19521#change-103599

* Author: ioquatix (Samuel Williams)
* Status: Open
* Priority: Normal
----------------------------------------
See https://bugs.ruby-lang.org/issues/19450 for previous discussion and motivation.

[This proposal](https://github.com/ruby/ruby/pull/7483) introduces `Module#name=` (and thus also `Class#name=`) to set the temporary class name. The name assignment has no effect if the module/class already has a permanent name.

```ruby
c = Class.new do
  self.name = "fake name"
end

c = Class.new
c.name = "fake name"
```

Alternatively, we could use `set_name`:

```ruby
Class.new do
  set_name "fake_name"
end
```

Setting the name of a class changes its current name, irrespective of whether it's been assigned a permanent name, or has nested modules/classes which have cached a previous name. We might like to limit the cases where a name is set, e.g. only once, only if the name is nil, or only if it's not already permanent. There is no real harm in any of those options, just inconsistency.

## Example usage

The current Ruby test suite has code which shows the usefulness of this new method:

```ruby
  def labeled_module(name, &block)
    Module.new do
      singleton_class.class_eval {
        define_method(:to_s) {name}
        alias inspect to_s
        alias name to_s
      }
      class_eval(&block) if block
    end
  end
  module_function :labeled_module

  def labeled_class(name, superclass = Object, &block)
    Class.new(superclass) do
      singleton_class.class_eval {
        define_method(:to_s) {name}
        alias inspect to_s
        alias name to_s
      }
      class_eval(&block) if block
    end
  end
  module_function :labeled_class
```

The updated code would look like this:

```ruby
  def labeled_module(name, &block)
    Module.new do
      self.name = name
      class_eval(&block) if block
    end
  end

  def labeled_class(name, superclass = Object, &block)
    Class.new(superclass) do
      self.name = name
      class_eval(&block) if block
    end
  end
  module_function :labeled_class
```

Because the name cannot be set as part of `.new`, we have to have a separate block to set the name, before calling `class_eval`. I think the ergonomics and performance of this are slightly worse than the [counter proposal](https://bugs.ruby-lang.org/issues/19520).



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/