[ruby-core:112809] [Ruby master Feature#19520] Support for `Module.new(name)` and `Class.new(superclass, name)`.
From:
"ioquatix (Samuel Williams) via ruby-core" <ruby-core@...>
Date:
2023-03-09 22:17:17 UTC
List:
ruby-core #112809
Issue #19520 has been updated by ioquatix (Samuel Williams).
> Usage in tests is not convincing to me, one could just assign those to e.g. Testing::Foo or so.
Your suggestion doesn't work well in practice, e.g. https://github.com/rspec/rspec-core/blob/d722da4a175f0347e4be1ba16c0eb763de48f07c/lib/rspec/core/example_group.rb#L895-L903
> uses `Module.instance_method(:name).bind_call(mod)`, and that's unaffected by `def c.name` but it would be by this new feature.
This already appears broken to me:
```ruby
m = Module.new
=> #<Module:0x00007f4ea0f5d160>
m.class_eval("class Bar;end")
bar = m::Bar
=> #<Module:0x00007f4ea0f5d160>::Bar
Module.instance_method(:name).bind_call(bar)
=> "#<Module:0x00007f4ea0f5d160>::Bar"
```
The name given here is not valid.
One way to resolve the above issue is to expose when a name is a valid permanent global name, or when it's a temporary anonymous name. e.g. `m.anonymous?` at least allows you to rule out types which are not expected to be resolved.
Unfortunately as I already demonstrated, even permanent global names can be fake/resolvable and it is trivial to construct such a case, so `!m.anonymous?` does not mean that `eval(m.name)` will result in anything useful.
----------------------------------------
Feature #19520: Support for `Module.new(name)` and `Class.new(superclass, name)`.
https://bugs.ruby-lang.org/issues/19520#change-102312
* 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/7376) introduces the `name` parameter to `Class.new` and `Module.new`:
```ruby
Class.new(superclass, name)
Module.new(name)
```
As a slight change, we could use keyword arguments instead.
## 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(name, &block)
end
def labeled_class(name, superclass = Object, &block)
Class.new(superclass, name, &block)
end
module_function :labeled_class
```
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- [email protected]
To unsubscribe send an email to [email protected]
ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/