Class: Kielce::KielceData
- Inherits:
- BasicObject
- Defined in:
- lib/kielce/kielce_data.rb
Overview
By extending BasicObject instead of Object, we don’t have to worry about user data conflicting with method names in Object or Kernel
the data.
(The strange “xx_kielce_” naming is to avoid conflicts with user-chosen names)
Constant Summary collapse
- @@error_output =
$stderr
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize(data, root = nil, obj_name = nil) ⇒ KielceData
constructor
A new instance of KielceData.
- #inspect ⇒ Object
- #is_a?(klass) ⇒ Boolean
-
#method_missing(name, *args, **keyword_args, &block) ⇒ Object
Provides the “magic” that allows users to access data using method syntax.
- #root ⇒ Object
Constructor Details
#initialize(data, root = nil, obj_name = nil) ⇒ KielceData
Returns a new instance of KielceData.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/kielce/kielce_data.rb', line 66 def initialize(data, root = nil, obj_name = nil) INVALID_KEYS.each do |key| ::Kernel.send(:raise, InvalidKeyError.new("Invalid Key: #{key} may not be used as a key.", key)) if data.has_key?(key) end @xx_kielce_obj_name = obj_name.nil? ? "" : obj_name @xx_kielce_data = data # Remember, root may be a BasicObject and, therefore, not define .nil @xx_kielce_root = (root == nil) ? self : root @xx_kielce_data.each do |key, value| if value.is_a?(::Hash) @xx_kielce_data[key] = ::Kielce::KielceData.new(value, @xx_kielce_root, "#{@xx_kielce_obj_name}#{key}.") end end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, **keyword_args, &block) ⇒ Object
Provides the “magic” that allows users to access data using method syntax. This method is called whenever a method that doesn’t exist is invoked. It then looks through the hash for a key with the same name as the method.
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/kielce/kielce_data.rb', line 101 def method_missing(name, *args, **keyword_args, &block) # $stderr.puts "Processing #{name} in #{@xx_kielce_obj_name}" # Convert the name to a symbol. (It is probably already a symbol, but the extra .to_sym won't hurt) # Then complian if there isn't a data object by that name. name_sym = name.to_sym full_name = "#{@xx_kielce_obj_name}#{name}" unless @xx_kielce_data.has_key?(name_sym) # The first ("message") parameter is currently unused. The message can be changed, if desired. ::Kernel.send(:raise, NoKeyError.new("Unrecognized Key: #{full_name}", full_name)) end # Get the requested data object. # If the object is a lambda, execute the lambda. # Otherwise, just return it. item = @xx_kielce_data[name_sym] if item.is_a?(::Proc) if item.parameters.any? { |i| i.last == :root } @@error_output.puts 'WARNING! Lambda parameter named root shadows instance method root.' end #$stderr.puts item.parameters.inspect keyword_params = item.parameters.select { |i| i.first == :keyreq || i.first == :key } num_keyword = keyword_params.size num_args = item.parameters.size - num_keyword #$stderr.puts "-----------" #$stderr.puts args.inspect #$stderr.puts keyword_args.inspect #$stderr.puts "Num each: #{num_args} #{num_keyword}" if num_args == 0 && num_keyword == 0 return instance_exec(&item) elsif num_args > 0 && num_keyword == 0 return instance_exec(*args, &item) elsif num_keyword > 0 return instance_exec(*args, **keyword_args, &item) else $stderr.puts "FAIL. Shouldn't get here!" end end if args.length != 0 || keyword_args.size != 0 @@error_output.puts "WARNING! #{full_name} is not a function and doesn't expect parameters." end @xx_kielce_data[name_sym] end |
Class Method Details
.error_output ⇒ Object
58 59 60 |
# File 'lib/kielce/kielce_data.rb', line 58 def self.error_output @@error_output end |
.error_output=(val) ⇒ Object
62 63 64 |
# File 'lib/kielce/kielce_data.rb', line 62 def self.error_output=(val) @@error_output=val end |
Instance Method Details
#inspect ⇒ Object
90 91 92 |
# File 'lib/kielce/kielce_data.rb', line 90 def inspect "KielceData: #{@xx_kielce_obj_name} #{@xx_kielce_data.inspect}" end |
#is_a?(klass) ⇒ Boolean
94 95 96 |
# File 'lib/kielce/kielce_data.rb', line 94 def is_a?(klass) klass == ::Kielce::KielceData end |
#root ⇒ Object
86 87 88 |
# File 'lib/kielce/kielce_data.rb', line 86 def root @xx_kielce_root end |