From: "kjtsanaktsidis (KJ Tsanaktsidis) via ruby-core" Date: 2023-12-29T05:50:53+00:00 Subject: [ruby-core:115974] [Ruby master Feature#20093] Syntax or keyword to reopen existing classs/modules, never to define new classs/modules Issue #20093 has been updated by kjtsanaktsidis (KJ Tsanaktsidis). > The only downside I see is that doesn't make it easy to define and access constants defined under that class/module. > A possibility in that case is to use class_eval(String) I actually found this quite surprising: ``` irb(main):008> String.class_eval { Module.nesting } => [] irb(main):009> String.class_eval "Module.nesting" => [String] ``` I get why the first one is empty (we're not inside a `class String ... end` block), but I find it surprising that the string form returns `String`. ---------------------------------------- Feature #20093: Syntax or keyword to reopen existing classs/modules, never to define new classs/modules https://bugs.ruby-lang.org/issues/20093#change-105937 * Author: tagomoris (Satoshi Tagomori) * Status: Open * Priority: Normal ---------------------------------------- `class A` and `module B` will reopen existing class A or module B to add/re-define methods if A/B exists. Otherwise, these will define the new class/module A/B. But, in my opinion, the code of `class A` for patching existing classes doesn't work expectedly when `A` is not defined beforehand. It expects other codes to define `A` before being called. For example: ```ruby # string_exclude.rb class String def exclude?(string) !include?(string) end end ``` This code expects that there is the `String` class, and it has the `include?` method. This code doesn't work if the file is loaded in the way below: ```ruby load('string_exclude.rb', true) ``` This code doesn't raise errors and will define an almost empty class (only with a method `exclude?` to raise NameError). It should be unexpected for every user. So, I want to propose a new syntax to reopen the existing class/module or raise errors if the specified class/module is not defined. ```ruby class extension String def exclude?(string) !include?(string) end end # adds #exclude? to String class class extension Stroooong def exclude?(string) !include?(string) end end # will raise NameError (or something else) ``` Some additional things: * `class extension String` (and `module extension String`) causes a compile error (SyntaxError) on Ruby 3.3. So we have space to add a keyword between class/module and the class/module name. * I don't have a strong opinion about the keyword name `extension`. An alternative idea is `reopen`. -- 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/