class-metrix 0.1.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +48 -0
  3. data/.vscode/README.md +72 -0
  4. data/.vscode/extensions.json +28 -0
  5. data/.vscode/launch.json +32 -0
  6. data/.vscode/settings.json +88 -0
  7. data/.vscode/tasks.json +99 -0
  8. data/CHANGELOG.md +71 -4
  9. data/README.md +41 -7
  10. data/docs/ARCHITECTURE.md +501 -0
  11. data/examples/README.md +161 -114
  12. data/examples/basic_usage.rb +88 -0
  13. data/examples/debug_levels_demo.rb +65 -0
  14. data/examples/debug_mode_demo.rb +75 -0
  15. data/examples/inheritance_and_modules.rb +155 -0
  16. data/lib/class_metrix/extractor.rb +106 -11
  17. data/lib/class_metrix/extractors/constants_extractor.rb +155 -21
  18. data/lib/class_metrix/extractors/methods_extractor.rb +186 -21
  19. data/lib/class_metrix/extractors/multi_type_extractor.rb +6 -5
  20. data/lib/class_metrix/formatters/components/footer_component.rb +1 -1
  21. data/lib/class_metrix/formatters/components/table_component/column_width_calculator.rb +56 -0
  22. data/lib/class_metrix/formatters/components/table_component/row_processor.rb +138 -0
  23. data/lib/class_metrix/formatters/components/table_component/table_data_extractor.rb +54 -0
  24. data/lib/class_metrix/formatters/components/table_component/table_renderer.rb +55 -0
  25. data/lib/class_metrix/formatters/components/table_component.rb +30 -244
  26. data/lib/class_metrix/formatters/shared/markdown_table_builder.rb +10 -5
  27. data/lib/class_metrix/formatters/shared/table_builder.rb +84 -21
  28. data/lib/class_metrix/formatters/shared/value_processor.rb +72 -16
  29. data/lib/class_metrix/utils/debug_logger.rb +159 -0
  30. data/lib/class_metrix/version.rb +1 -1
  31. metadata +17 -9
  32. data/examples/advanced/error_handling.rb +0 -199
  33. data/examples/advanced/hash_expansion.rb +0 -180
  34. data/examples/basic/01_simple_constants.rb +0 -56
  35. data/examples/basic/02_simple_methods.rb +0 -99
  36. data/examples/basic/03_multi_type_extraction.rb +0 -116
  37. data/examples/components/configurable_reports.rb +0 -201
  38. data/examples/csv_output_demo.rb +0 -237
  39. data/examples/real_world/microservices_audit.rb +0 -312
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ClassMetrix
4
+ module Utils
5
+ # Debug logging utility for ClassMetrix
6
+ # Provides safe, consistent debug output across all components
7
+ class DebugLogger
8
+ # Debug levels: :basic, :detailed, :verbose
9
+ LEVELS = { basic: 1, detailed: 2, verbose: 3 }.freeze
10
+
11
+ def initialize(component_name, debug_mode = false, level = :basic)
12
+ @component_name = component_name
13
+ @debug_mode = debug_mode
14
+ @level = LEVELS[level] || LEVELS[:basic]
15
+ end
16
+
17
+ def log(message, level = :basic)
18
+ return unless @debug_mode && LEVELS[level] <= @level
19
+
20
+ puts "[DEBUG #{@component_name}] #{message}"
21
+ end
22
+
23
+ def log_safe_operation(operation_name, level = :detailed, &block)
24
+ log("Starting #{operation_name}", level)
25
+ result = block.call
26
+ log("Completed #{operation_name} successfully", level)
27
+ result
28
+ rescue StandardError => e
29
+ log("Error in #{operation_name}: #{e.class.name}: #{e.message}")
30
+ raise
31
+ end
32
+
33
+ # Summary logging for groups of similar operations
34
+ def log_summary(operation, items, &block)
35
+ return unless @debug_mode
36
+
37
+ if @level >= LEVELS[:detailed]
38
+ log("#{operation} (#{items.length} items)")
39
+ items.each_with_index { |item, i| block.call(item, i) } if block_given?
40
+ else
41
+ log("#{operation} (#{items.length} items)")
42
+ end
43
+ end
44
+
45
+ def log_decision(decision, reason, level = :basic)
46
+ log("Decision: #{decision} - #{reason}", level)
47
+ end
48
+
49
+ def log_anomaly(description)
50
+ log("⚠️ Anomaly: #{description}")
51
+ end
52
+
53
+ # Safe inspection methods to handle problematic objects
54
+ def safe_inspect(value)
55
+ value.inspect
56
+ rescue StandardError => e
57
+ "[inspect failed: #{e.class.name}]"
58
+ end
59
+
60
+ def safe_class(value)
61
+ value.class
62
+ rescue StandardError => e
63
+ "[class failed: #{e.class.name}]"
64
+ end
65
+
66
+ def safe_keys(value)
67
+ value.keys
68
+ rescue StandardError => e
69
+ "[keys failed: #{e.class.name}]"
70
+ end
71
+
72
+ def safe_length(value)
73
+ value.length
74
+ rescue StandardError
75
+ "[length failed]"
76
+ end
77
+
78
+ def safe_truncate(str, max_length)
79
+ return str unless str.respond_to?(:length) && str.respond_to?(:[])
80
+
81
+ str.length > max_length ? "#{str[0...max_length]}..." : str
82
+ rescue StandardError => e
83
+ "[truncate failed: #{e.class.name}]"
84
+ end
85
+
86
+ def safe_to_s(value)
87
+ value.to_s
88
+ rescue StandardError => e
89
+ begin
90
+ value.class.name
91
+ rescue StandardError => e2
92
+ "[to_s failed: #{e.class.name}, class failed: #{e2.class.name}]"
93
+ end
94
+ end
95
+
96
+ def log_value_details(value, index = nil, level = :verbose)
97
+ return unless @debug_mode && @level >= LEVELS[level]
98
+
99
+ prefix = index ? "Value #{index}" : "Value"
100
+ log("#{prefix}: #{safe_inspect(value)} (#{safe_class(value)})", level)
101
+ end
102
+
103
+ def log_hash_detection(value, index = nil, level = :detailed)
104
+ return unless @debug_mode && @level >= LEVELS[level]
105
+
106
+ prefix = index ? "Value #{index}" : "Value"
107
+ is_hash = value.is_a?(Hash)
108
+ is_real_hash = value.is_a?(Hash) && value.instance_of?(Hash)
109
+
110
+ return unless is_hash
111
+
112
+ log("#{prefix} hash detection:")
113
+ log(" is_a?(Hash): #{is_hash}, class == Hash: #{is_real_hash}")
114
+ log(" respond_to?(:keys): #{value.respond_to?(:keys)}")
115
+
116
+ if is_hash && is_real_hash
117
+ log(" keys: #{safe_keys(value)}")
118
+ elsif is_hash
119
+ log_anomaly("Hash-like object (#{safe_class(value)}) but not real Hash - will be skipped")
120
+ end
121
+ end
122
+
123
+ # Smart hash detection summary
124
+ def log_hash_detection_summary(values)
125
+ return unless @debug_mode
126
+
127
+ hash_count = 0
128
+ real_hash_count = 0
129
+ anomaly_count = 0
130
+
131
+ values.each do |value|
132
+ next unless value.is_a?(Hash)
133
+
134
+ hash_count += 1
135
+ if value.instance_of?(Hash)
136
+ real_hash_count += 1
137
+ else
138
+ anomaly_count += 1
139
+ end
140
+ end
141
+
142
+ return unless hash_count.positive?
143
+
144
+ log("Hash detection summary: #{real_hash_count} real hashes, #{anomaly_count} hash-like objects")
145
+ log_anomaly("Found #{anomaly_count} hash-like proxy objects") if anomaly_count.positive?
146
+ end
147
+
148
+ def enabled?
149
+ @debug_mode
150
+ end
151
+
152
+ attr_reader :level
153
+
154
+ def set_level(level)
155
+ @level = LEVELS[level] || LEVELS[:basic]
156
+ end
157
+ end
158
+ end
159
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ClassMetrix
4
- VERSION = "0.1.2"
4
+ VERSION = "1.0.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: class-metrix
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Huy Nguyen
@@ -47,23 +47,26 @@ executables: []
47
47
  extensions: []
48
48
  extra_rdoc_files: []
49
49
  files:
50
+ - ".editorconfig"
50
51
  - ".rspec"
51
52
  - ".rubocop.yml"
52
53
  - ".tool-versions"
54
+ - ".vscode/README.md"
55
+ - ".vscode/extensions.json"
56
+ - ".vscode/launch.json"
57
+ - ".vscode/settings.json"
58
+ - ".vscode/tasks.json"
53
59
  - CHANGELOG.md
54
60
  - LICENSE.txt
55
61
  - README.md
56
62
  - RELEASE_GUIDE.md
57
63
  - Rakefile
64
+ - docs/ARCHITECTURE.md
58
65
  - examples/README.md
59
- - examples/advanced/error_handling.rb
60
- - examples/advanced/hash_expansion.rb
61
- - examples/basic/01_simple_constants.rb
62
- - examples/basic/02_simple_methods.rb
63
- - examples/basic/03_multi_type_extraction.rb
64
- - examples/components/configurable_reports.rb
65
- - examples/csv_output_demo.rb
66
- - examples/real_world/microservices_audit.rb
66
+ - examples/basic_usage.rb
67
+ - examples/debug_levels_demo.rb
68
+ - examples/debug_mode_demo.rb
69
+ - examples/inheritance_and_modules.rb
67
70
  - lib/class_metrix.rb
68
71
  - lib/class_metrix/extractor.rb
69
72
  - lib/class_metrix/extractors/constants_extractor.rb
@@ -76,6 +79,10 @@ files:
76
79
  - lib/class_metrix/formatters/components/header_component.rb
77
80
  - lib/class_metrix/formatters/components/missing_behaviors_component.rb
78
81
  - lib/class_metrix/formatters/components/table_component.rb
82
+ - lib/class_metrix/formatters/components/table_component/column_width_calculator.rb
83
+ - lib/class_metrix/formatters/components/table_component/row_processor.rb
84
+ - lib/class_metrix/formatters/components/table_component/table_data_extractor.rb
85
+ - lib/class_metrix/formatters/components/table_component/table_renderer.rb
79
86
  - lib/class_metrix/formatters/csv_formatter.rb
80
87
  - lib/class_metrix/formatters/markdown_formatter.rb
81
88
  - lib/class_metrix/formatters/shared/csv_table_builder.rb
@@ -84,6 +91,7 @@ files:
84
91
  - lib/class_metrix/formatters/shared/value_processor.rb
85
92
  - lib/class_metrix/processors/value_processor.rb
86
93
  - lib/class_metrix/utils/class_resolver.rb
94
+ - lib/class_metrix/utils/debug_logger.rb
87
95
  - lib/class_metrix/version.rb
88
96
  - sig/class/metrix.rbs
89
97
  homepage: https://github.com/patrick204nqh/class-metrix
@@ -1,199 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require_relative "../../lib/class_metrix"
5
-
6
- puts "=== Advanced Example: Error Handling ==="
7
- puts
8
-
9
- # Classes that demonstrate various error scenarios
10
- class WorkingService
11
- # Working constants
12
- SERVICE_NAME = "working"
13
- VERSION = "1.0.0"
14
- ENABLED = true
15
-
16
- # Working methods
17
- def self.status
18
- "healthy"
19
- end
20
-
21
- def self.version
22
- "1.0.0"
23
- end
24
-
25
- def self.health_check
26
- { status: "ok", uptime: 12_345 }
27
- end
28
-
29
- def self.enabled?
30
- true
31
- end
32
- end
33
-
34
- class PartiallyBrokenService
35
- # Working constants
36
- SERVICE_NAME = "partially_broken"
37
- VERSION = "0.9.0"
38
- # Missing ENABLED constant
39
-
40
- # Working methods
41
- def self.status
42
- "degraded"
43
- end
44
-
45
- def self.version
46
- "0.9.0"
47
- end
48
-
49
- # Broken method that raises an error
50
- def self.health_check
51
- raise StandardError, "Health check failed!"
52
- end
53
-
54
- def self.enabled?
55
- false
56
- end
57
-
58
- # Method that returns nil
59
- def self.uptime
60
- nil
61
- end
62
-
63
- # Method with complex error
64
- def self.database_connection
65
- raise ActiveRecord::ConnectionNotEstablished, "Database unavailable"
66
- rescue NameError
67
- # If ActiveRecord is not available, raise a different error
68
- raise "Connection library not available"
69
- end
70
- end
71
-
72
- class CompletelyBrokenService
73
- # Has some constants
74
- SERVICE_NAME = "broken"
75
- # Missing VERSION and ENABLED
76
-
77
- # Has working method
78
- def self.status
79
- "down"
80
- end
81
-
82
- # Missing version method
83
-
84
- # Broken health_check
85
- def self.health_check
86
- raise NoMethodError, "Health monitoring not implemented"
87
- end
88
-
89
- # Method that raises during execution
90
- def self.enabled?
91
- some_undefined_variable.call
92
- end
93
-
94
- # Method that returns false
95
- def self.deprecated?
96
- true
97
- end
98
- end
99
-
100
- puts "=== Service Classes Defined ==="
101
- puts "WorkingService: All methods work"
102
- puts "PartiallyBrokenService: Some methods fail"
103
- puts "CompletelyBrokenService: Most methods fail"
104
- puts
105
-
106
- # 1. Extract without error handling (will raise errors)
107
- puts "💥 1. WITHOUT ERROR HANDLING (This will show errors)"
108
- puts "-" * 60
109
-
110
- begin
111
- result = ClassMetrix.extract(:class_methods)
112
- .from([WorkingService, PartiallyBrokenService])
113
- .filter(/health_check/)
114
- .to_markdown
115
- puts result
116
- rescue StandardError => e
117
- puts "❌ Error occurred: #{e.class.name}: #{e.message}"
118
- end
119
- puts
120
-
121
- # 2. Extract with error handling
122
- puts "🛡️ 2. WITH ERROR HANDLING (Graceful failure)"
123
- puts "-" * 60
124
- result = ClassMetrix.extract(:class_methods)
125
- .from([WorkingService, PartiallyBrokenService, CompletelyBrokenService])
126
- .handle_errors
127
- .to_markdown
128
-
129
- puts result
130
- puts
131
-
132
- # 3. Constants with missing values
133
- puts "📋 3. CONSTANTS WITH MISSING VALUES"
134
- puts "-" * 60
135
- result = ClassMetrix.extract(:constants)
136
- .from([WorkingService, PartiallyBrokenService, CompletelyBrokenService])
137
- .handle_errors
138
- .to_markdown
139
-
140
- puts result
141
- puts
142
-
143
- # 4. Multi-type extraction with errors
144
- puts "📊 4. MULTI-TYPE WITH ERROR HANDLING"
145
- puts "-" * 60
146
- result = ClassMetrix.extract(:constants, :class_methods)
147
- .from([WorkingService, PartiallyBrokenService, CompletelyBrokenService])
148
- .filter(/SERVICE_NAME|status|enabled/)
149
- .handle_errors
150
- .to_markdown
151
-
152
- puts result
153
- puts
154
-
155
- # 5. Focus on problematic methods
156
- puts "🔍 5. PROBLEMATIC METHODS ANALYSIS"
157
- puts "-" * 60
158
- result = ClassMetrix.extract(:class_methods)
159
- .from([WorkingService, PartiallyBrokenService, CompletelyBrokenService])
160
- .filter(/health_check|database|uptime/)
161
- .handle_errors
162
- .to_markdown
163
-
164
- puts result
165
- puts
166
-
167
- # 6. Boolean and nil value handling
168
- puts "✅ 6. BOOLEAN AND NIL VALUE HANDLING"
169
- puts "-" * 60
170
- result = ClassMetrix.extract(:class_methods)
171
- .from([WorkingService, PartiallyBrokenService, CompletelyBrokenService])
172
- .filter(/enabled\?|deprecated\?|uptime/)
173
- .handle_errors
174
- .to_markdown
175
-
176
- puts result
177
- puts
178
-
179
- # 7. Save comprehensive error analysis report
180
- puts "💾 7. SAVING COMPREHENSIVE ERROR ANALYSIS REPORT"
181
- puts "-" * 60
182
- report = ClassMetrix.extract(:constants, :class_methods)
183
- .from([WorkingService, PartiallyBrokenService, CompletelyBrokenService])
184
- .handle_errors
185
- .to_markdown("error_analysis_report.md", title: "Service Health Analysis Report")
186
-
187
- puts "✅ Comprehensive error analysis saved to: error_analysis_report.md"
188
- puts "📊 Report contains #{report.lines.count} lines with rich metadata"
189
- puts
190
-
191
- puts "🛡️ Enhanced Error Handling Features Demonstrated:"
192
- puts "• 🚫 Missing constants: '🚫 Not defined'"
193
- puts "• 🚫 Missing methods: '🚫 No method'"
194
- puts "• ⚠️ Runtime errors: '⚠️ Error: [descriptive message]'"
195
- puts "• ❌ Boolean false and nil values: '❌'"
196
- puts "• ✅ Boolean true values: '✅'"
197
- puts "• 📊 Rich markdown reports with titles and metadata"
198
- puts "• 📋 Missing behaviors summary per class"
199
- puts "• 🛡️ handle_errors flag enables graceful degradation"
@@ -1,180 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require_relative "../../lib/class_metrix"
5
-
6
- puts "=== Advanced Example: Hash Expansion ==="
7
- puts
8
-
9
- # Configuration classes with complex hash structures
10
- class DatabaseConfig
11
- # Hash constants
12
- DEFAULT_CONFIG = {
13
- host: "localhost",
14
- port: 5432,
15
- ssl: true,
16
- pool_size: 5
17
- }.freeze
18
-
19
- CONNECTION_POOLS = {
20
- read: { size: 10, timeout: 30 },
21
- write: { size: 5, timeout: 15 },
22
- admin: { size: 2, timeout: 60 }
23
- }.freeze
24
-
25
- # Hash methods
26
- def self.production_config
27
- {
28
- host: "db.production.com",
29
- port: 5432,
30
- database: "myapp_production",
31
- ssl: true,
32
- pool_size: 20,
33
- timeout: 30,
34
- backup_enabled: true
35
- }
36
- end
37
-
38
- def self.development_config
39
- {
40
- host: "localhost",
41
- port: 5432,
42
- database: "myapp_development",
43
- ssl: false,
44
- pool_size: 5,
45
- timeout: 10
46
- }
47
- end
48
-
49
- def self.simple_value
50
- "not a hash"
51
- end
52
- end
53
-
54
- class RedisConfig
55
- # Hash constants
56
- DEFAULT_CONFIG = {
57
- host: "localhost",
58
- port: 6379,
59
- ssl: false,
60
- timeout: 5
61
- }.freeze
62
-
63
- CLUSTER_CONFIG = {
64
- nodes: 3,
65
- replication: true,
66
- failover: "auto"
67
- }.freeze
68
-
69
- # Hash methods
70
- def self.production_config
71
- {
72
- host: "redis.internal",
73
- port: 6379,
74
- database: 0,
75
- ssl: false,
76
- max_connections: 100,
77
- cluster_enabled: true
78
- }
79
- end
80
-
81
- def self.development_config
82
- {
83
- host: "localhost",
84
- port: 6379,
85
- database: 1,
86
- ssl: false,
87
- max_connections: 10
88
- }
89
- end
90
-
91
- def self.simple_value
92
- 42
93
- end
94
- end
95
-
96
- puts "=== Configuration Classes Defined ==="
97
- puts "DatabaseConfig and RedisConfig with hash constants and methods"
98
- puts
99
-
100
- # 1. Normal output (without expansion)
101
- puts "📋 1. NORMAL OUTPUT (Hashes as inspect strings)"
102
- puts "-" * 60
103
- result = ClassMetrix.extract(:class_methods)
104
- .from([DatabaseConfig, RedisConfig])
105
- .filter(/config$/)
106
- .to_markdown
107
-
108
- puts result
109
- puts
110
-
111
- # 2. Expanded output
112
- puts "🔍 2. EXPANDED OUTPUT (Hash keys as sub-rows)"
113
- puts "-" * 60
114
- result = ClassMetrix.extract(:class_methods)
115
- .from([DatabaseConfig, RedisConfig])
116
- .filter(/config$/)
117
- .expand_hashes
118
- .to_markdown
119
-
120
- puts result
121
- puts
122
-
123
- # 3. Constants with expansion
124
- puts "📊 3. CONSTANTS WITH HASH EXPANSION"
125
- puts "-" * 60
126
- result = ClassMetrix.extract(:constants)
127
- .from([DatabaseConfig, RedisConfig])
128
- .filter(/CONFIG/)
129
- .expand_hashes
130
- .handle_errors
131
- .to_markdown
132
-
133
- puts result
134
- puts
135
-
136
- # 4. Mixed data types with expansion
137
- puts "🔧 4. MIXED DATA TYPES WITH EXPANSION"
138
- puts "-" * 60
139
- result = ClassMetrix.extract(:class_methods)
140
- .from([DatabaseConfig, RedisConfig])
141
- .expand_hashes
142
- .to_markdown
143
-
144
- puts result
145
- puts
146
-
147
- # 5. Multi-type extraction with expansion
148
- puts "🚀 5. MULTI-TYPE WITH HASH EXPANSION"
149
- puts "-" * 60
150
- result = ClassMetrix.extract(:constants, :class_methods)
151
- .from([DatabaseConfig, RedisConfig])
152
- .filter(/DEFAULT_CONFIG|production_config/)
153
- .expand_hashes
154
- .handle_errors
155
- .to_markdown
156
-
157
- puts result
158
- puts
159
-
160
- # 6. Save expanded report
161
- puts "💾 6. SAVING EXPANDED REPORT"
162
- puts "-" * 60
163
- report = ClassMetrix.extract(:constants, :class_methods)
164
- .from([DatabaseConfig, RedisConfig])
165
- .expand_hashes
166
- .handle_errors
167
- .to_markdown("config_analysis_expanded.md")
168
-
169
- puts "✅ Expanded report saved to: config_analysis_expanded.md"
170
- puts "📊 Report contains #{report.lines.count} lines"
171
- puts
172
-
173
- puts "✨ Hash Expansion Features Demonstrated:"
174
- puts "• 📋 Hash indicators show number of keys"
175
- puts "• └─ Sub-rows show individual key-value pairs"
176
- puts "• ❌ Missing keys shown clearly"
177
- puts "• — Non-hash values shown with dash"
178
- puts "• Mixed data types handled properly"
179
- puts "• Works with both constants and methods"
180
- puts "• Compatible with multi-type extraction"
@@ -1,56 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require_relative "../../lib/class_metrix"
5
-
6
- puts "=== Basic Example 1: Simple Constants ==="
7
- puts
8
-
9
- # Define some simple classes with constants
10
- class User
11
- ROLE_NAME = "user"
12
- MAX_LOGIN_ATTEMPTS = 3
13
- ACCOUNT_TYPE = "standard"
14
- end
15
-
16
- class Admin
17
- ROLE_NAME = "admin"
18
- MAX_LOGIN_ATTEMPTS = 5
19
- ACCOUNT_TYPE = "premium"
20
- ADMIN_LEVEL = 10
21
- end
22
-
23
- class Guest
24
- ROLE_NAME = "guest"
25
- MAX_LOGIN_ATTEMPTS = 1
26
- ACCOUNT_TYPE = "basic"
27
- end
28
-
29
- puts "Classes defined: User, Admin, Guest"
30
- puts "Constants: ROLE_NAME, MAX_LOGIN_ATTEMPTS, ACCOUNT_TYPE, ADMIN_LEVEL"
31
- puts
32
-
33
- # Extract all constants
34
- puts "📋 All Constants:"
35
- puts ClassMetrix.extract(:constants)
36
- .from([User, Admin, Guest])
37
- .to_markdown
38
- puts
39
-
40
- # Extract filtered constants
41
- puts "🔍 Filtered Constants (ROLE and MAX):"
42
- puts ClassMetrix.extract(:constants)
43
- .from([User, Admin, Guest])
44
- .filter(/ROLE|MAX/)
45
- .to_markdown
46
- puts
47
-
48
- # Extract with regex filter
49
- puts "🎯 Regex Filter (starting with ACCOUNT):"
50
- puts ClassMetrix.extract(:constants)
51
- .from([User, Admin, Guest])
52
- .filter(/^ACCOUNT/)
53
- .to_markdown
54
- puts
55
-
56
- puts "✨ This example shows basic constant extraction and filtering!"