Class: LoggedStruct
Overview
LoggedStruct behaves like OpenStruct but logs all get and set operations on its attributes, providing visibility into how the object is used.
Instance Attribute Summary collapse
-
#log_buffer ⇒ Object
readonly
Returns the value of attribute log_buffer.
-
#logger ⇒ Object
readonly
Returns the value of attribute logger.
Instance Method Summary collapse
-
#[](name) ⇒ Object
Logs attribute retrieval.
-
#[]=(name, value) ⇒ Object
Logs attribute setting.
-
#ensure_logging_methods(name) ⇒ Object
Installs logging versions of getters and setters.
-
#initialize(hash = nil, logger: nil, log_level: :debug) ⇒ LoggedStruct
constructor
Initializes a new LoggedStruct.
-
#log_content ⇒ Object
Returns the internal log buffer.
-
#method_missing(method, *args, &block) ⇒ Object
Delegates missing method calls.
-
#new_ostruct_member(name) ⇒ Object
Overrides OpenStruct’s member creation to install logging methods.
-
#respond_to_missing?(method, include_private = false) ⇒ Boolean
Checks if a method exists.
-
#to_h ⇒ Object
Logs conversion to a hash.
Constructor Details
#initialize(hash = nil, logger: nil, log_level: :debug) ⇒ LoggedStruct
Initializes a new LoggedStruct.
19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/logged_struct.rb', line 19 def initialize(hash = nil, logger: nil, log_level: :debug) @log_buffer = StringIO.new @custom_log_level = log_level.to_sym @logger = logger || Logger.new($stdout) @logger.level = Logger.const_get(@custom_log_level.to_s.upcase) @logger.formatter ||= proc { |severity, datetime, progname, msg| "#{msg}\n" } super({}) (hash || {}).each { |key, value| self[key] = value } end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
Delegates missing method calls.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/logged_struct.rb', line 78 def method_missing(method, *args, &block) method_name = method.to_s if method_name.end_with?('=') attribute = method_name.chop self[attribute] = args.first else # If arguments are provided, delegate to super to raise NoMethodError. if args.empty? self[method_name] else super end end end |
Instance Attribute Details
#log_buffer ⇒ Object (readonly)
Returns the value of attribute log_buffer.
13 14 15 |
# File 'lib/logged_struct.rb', line 13 def log_buffer @log_buffer end |
#logger ⇒ Object (readonly)
Returns the value of attribute logger.
13 14 15 |
# File 'lib/logged_struct.rb', line 13 def logger @logger end |
Instance Method Details
#[](name) ⇒ Object
Logs attribute retrieval.
32 33 34 35 36 |
# File 'lib/logged_struct.rb', line 32 def [](name) value = super log_get_operation(name.to_s, value) value end |
#[]=(name, value) ⇒ Object
Logs attribute setting.
39 40 41 42 43 44 |
# File 'lib/logged_struct.rb', line 39 def []=(name, value) log_set_operation(name.to_s, value) super ensure_logging_methods(name.to_sym) value end |
#ensure_logging_methods(name) ⇒ Object
Installs logging versions of getters and setters.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/logged_struct.rb', line 56 def ensure_logging_methods(name) eigen = singleton_class if eigen.method_defined?(name) && eigen.instance_method(name).owner == eigen eigen.send(:remove_method, name) end if eigen.method_defined?("#{name}=") && eigen.instance_method("#{name}=").owner == eigen eigen.send(:remove_method, "#{name}=") end eigen.define_method(name) do value = @table[name] log_get_operation(name.to_s, value) value end eigen.define_method("#{name}=") do |value| log_set_operation(name.to_s, value) @table[name] = value end end |
#log_content ⇒ Object
Returns the internal log buffer.
108 109 110 |
# File 'lib/logged_struct.rb', line 108 def log_content @log_buffer.string end |
#new_ostruct_member(name) ⇒ Object
Overrides OpenStruct’s member creation to install logging methods.
47 48 49 50 51 52 |
# File 'lib/logged_struct.rb', line 47 def new_ostruct_member(name) name = name.to_sym result = super ensure_logging_methods(name) result end |
#respond_to_missing?(method, include_private = false) ⇒ Boolean
Checks if a method exists.
94 95 96 97 98 |
# File 'lib/logged_struct.rb', line 94 def respond_to_missing?(method, include_private = false) method_name = method.to_s return true if method_name.end_with?('=') @table.key?(method) || super end |
#to_h ⇒ Object
Logs conversion to a hash.
101 102 103 104 105 |
# File 'lib/logged_struct.rb', line 101 def to_h hash = super ("Converting LoggedStruct to Hash: #{hash.inspect}") hash end |