From 91ea0ca502928553f23635dbb44122f12e001ea3 Mon Sep 17 00:00:00 2001 From: Anton Sokolov Date: Fri, 13 Feb 2026 17:42:05 +0300 Subject: [PATCH] Label generated DSL modules for improved debugging clarity - Add `label_module` method to assign descriptive labels to anonymous modules. - Modify `generate` to label the DSL module and `ClassMethods` with matrix-specific names. - Update tests to validate module labeling for both `inspect` and `to_s` output. - Use `set_temporary_name` for Ruby 3.3+ to set module names, falling back to `define_singleton_method` for earlier versions. - Adjust RuboCop exclusions for updated methods. --- lib/stroma/dsl/generator.rb | 25 +++++++++++++++++++++++-- sig/lib/stroma/dsl/generator.rbs | 2 ++ spec/stroma/dsl/generator_spec.rb | 19 +++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/stroma/dsl/generator.rb b/lib/stroma/dsl/generator.rb index f1308ac..365a336 100644 --- a/lib/stroma/dsl/generator.rb +++ b/lib/stroma/dsl/generator.rb @@ -59,11 +59,11 @@ def initialize(matrix) # - extensions DSL for registering hooks # # @return [Module] The generated DSL module - def generate # rubocop:disable Metrics/MethodLength + def generate # rubocop:disable Metrics/AbcSize, Metrics/MethodLength matrix = @matrix class_methods = build_class_methods - Module.new do + mod = Module.new do @stroma_matrix = matrix class << self @@ -81,10 +81,31 @@ def included(base) const_set(:ClassMethods, class_methods) end + + label_module(mod, "Stroma::DSL(#{matrix.name})") + label_module(class_methods, "Stroma::DSL(#{matrix.name})::ClassMethods") + + mod end private + # Assigns a descriptive label to an anonymous module for debugging. + # Uses set_temporary_name (Ruby 3.3+) when available. + # + # TODO: Remove the else branch when Ruby 3.2 support is dropped. + # The define_singleton_method fallback is a temporary workaround + # that only affects #inspect and #to_s. Unlike set_temporary_name, + # it does not set #name, so the module remains technically anonymous. + def label_module(mod, label) + if mod.respond_to?(:set_temporary_name) + mod.set_temporary_name(label) + else + mod.define_singleton_method(:inspect) { label } + mod.define_singleton_method(:to_s) { label } + end + end + # Builds the ClassMethods module. # # @return [Module] The ClassMethods module diff --git a/sig/lib/stroma/dsl/generator.rbs b/sig/lib/stroma/dsl/generator.rbs index 8953dbe..6411754 100644 --- a/sig/lib/stroma/dsl/generator.rbs +++ b/sig/lib/stroma/dsl/generator.rbs @@ -11,6 +11,8 @@ module Stroma private + def label_module: (Module mod, String label) -> void + def build_class_methods: () -> Module end end diff --git a/spec/stroma/dsl/generator_spec.rb b/spec/stroma/dsl/generator_spec.rb index ec8aa8f..c2f5b2c 100644 --- a/spec/stroma/dsl/generator_spec.rb +++ b/spec/stroma/dsl/generator_spec.rb @@ -23,6 +23,25 @@ it "stores matrix reference" do expect(dsl_module.stroma_matrix).to eq(matrix) end + + describe "module labeling" do + it "labels DSL module with matrix name", :aggregate_failures do + expect(dsl_module.inspect).to eq("Stroma::DSL(test)") + expect(dsl_module.to_s).to eq("Stroma::DSL(test)") + end + + it "labels ClassMethods with matrix name", :aggregate_failures do + class_methods = dsl_module.const_get(:ClassMethods) + expect(class_methods.inspect).to include("Stroma::DSL(test)") + expect(class_methods.inspect).to include("ClassMethods") + end + + if Module.new.respond_to?(:set_temporary_name) + it "sets module name via set_temporary_name" do + expect(dsl_module.name).to eq("Stroma::DSL(test)") + end + end + end end describe "generated module" do