Class: Cisco::CmdRef
- Inherits:
-
Object
- Object
- Cisco::CmdRef
- Defined in:
- lib/cisco_node_utils/command_reference.rb
Overview
Control a reference for an attribute.
Direct Known Subclasses
Constant Summary collapse
- KEYS =
%w(default_value default_only data_format context value get_data_format get_command get_context get_value set_data_format set_context set_value auto_default multiple kind)
- KINDS =
%w(boolean int string symbol)
Instance Attribute Summary collapse
-
#auto_default ⇒ Object
(also: #auto_default?)
readonly
Returns the value of attribute auto_default.
-
#default_only ⇒ Object
(also: #default_only?)
readonly
Returns the value of attribute default_only.
-
#feature ⇒ Object
readonly
Returns the value of attribute feature.
-
#hash ⇒ Object
readonly
Returns the value of attribute hash.
-
#kind ⇒ Object
readonly
Returns the value of attribute kind.
-
#multiple ⇒ Object
(also: #multiple?)
readonly
Returns the value of attribute multiple.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Class Method Summary collapse
Instance Method Summary collapse
-
#boolean_default_true(value) ⇒ Object
Property with an implicit value of ‘true’ if no value is given.
- #convert_to_constant(value) ⇒ Object
-
#define_helper(method_name, base_hash) ⇒ Object
Create a helper method for generating the getter/setter values.
- #define_key_value_helper(method_name, base_hash) ⇒ Object
- #define_printf_helper(method_name, base_hash, arg_count) ⇒ Object
- #define_static_helper(method_name, base_hash) ⇒ Object
-
#getter(*args, **kwargs) ⇒ Object
Default getter method.
-
#getter? ⇒ Boolean
Does this instance have a valid getter() function? Will be overridden at initialization if so.
-
#initialize(feature, name, values, file) ⇒ CmdRef
constructor
Construct a CmdRef describing the given (feature, name) pair.
- #key_substitutor(item, kwargs) ⇒ Object
- #method_missing(method_name, *args, &block) ⇒ Object
- #printf_substitutor(item, args) ⇒ Object
-
#setter(*args, **kwargs) ⇒ Object
Default setter method.
-
#setter? ⇒ Boolean
Does this instance have a valid setter() function? Will be overridden at initialization if so.
-
#to_s ⇒ Object
Print useful debugging information about the object.
- #values_to_hash(values, file) ⇒ Object
Constructor Details
#initialize(feature, name, values, file) ⇒ CmdRef
Construct a CmdRef describing the given (feature, name) pair. Param “values” is a hash with keys as described in KEYS. Param “file” is for debugging purposes only.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/cisco_node_utils/command_reference.rb', line 42 def initialize(feature, name, values, file) fail ArgumentError, "'#{values}' is not a hash." unless values.is_a? Hash @feature = feature @name = name @auto_default = true @default_only = false @multiple = false @kind = nil values_to_hash(values, file) if @hash['get_value'] || @hash['get_command'] define_helper('getter', data_format: @hash['get_data_format'] || :cli, command: @hash['get_command'], context: @hash['get_context'] || [], value: @hash['get_value']) end if @hash['set_value'] # rubocop:disable Style/GuardClause define_helper('setter', data_format: @hash['set_data_format'] || :cli, context: @hash['set_context'] || [], values: @hash['set_value']) end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args, &block) ⇒ Object
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/cisco_node_utils/command_reference.rb', line 297 def method_missing(method_name, *args, &block) if KEYS.include?(method_name.to_s) # ref.foo -> return @hash[foo] or fail IndexError method_name = method_name.to_s unless @hash.include?(method_name) if @default_only fail UnsupportedError.new(@feature, @name, method_name) end fail IndexError, "No #{method_name} defined for #{@feature}, #{@name}" end # puts("get #{method_name}: '#{@hash[method_name]}'") @hash[method_name] elsif method_name.to_s[-1] == '?' && \ KEYS.include?(method_name.to_s[0..-2]) # ref.foo? -> return true if @hash[foo], else false method_name = method_name.to_s[0..-2] @hash.include?(method_name) else super(method_name, *args, &block) end end |
Instance Attribute Details
#auto_default ⇒ Object (readonly) Also known as: auto_default?
Returns the value of attribute auto_default.
22 23 24 |
# File 'lib/cisco_node_utils/command_reference.rb', line 22 def auto_default @auto_default end |
#default_only ⇒ Object (readonly) Also known as: default_only?
Returns the value of attribute default_only.
22 23 24 |
# File 'lib/cisco_node_utils/command_reference.rb', line 22 def default_only @default_only end |
#feature ⇒ Object (readonly)
Returns the value of attribute feature.
21 22 23 |
# File 'lib/cisco_node_utils/command_reference.rb', line 21 def feature @feature end |
#hash ⇒ Object (readonly)
Returns the value of attribute hash.
21 22 23 |
# File 'lib/cisco_node_utils/command_reference.rb', line 21 def hash @hash end |
#kind ⇒ Object (readonly)
Returns the value of attribute kind.
22 23 24 |
# File 'lib/cisco_node_utils/command_reference.rb', line 22 def kind @kind end |
#multiple ⇒ Object (readonly) Also known as: multiple?
Returns the value of attribute multiple.
22 23 24 |
# File 'lib/cisco_node_utils/command_reference.rb', line 22 def multiple @multiple end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
21 22 23 |
# File 'lib/cisco_node_utils/command_reference.rb', line 21 def name @name end |
Class Method Details
.keys ⇒ Object
33 34 35 |
# File 'lib/cisco_node_utils/command_reference.rb', line 33 def self.keys KEYS end |
Instance Method Details
#boolean_default_true(value) ⇒ Object
Property with an implicit value of ‘true’ if no value is given
157 158 159 |
# File 'lib/cisco_node_utils/command_reference.rb', line 157 def boolean_default_true(value) value.nil? || value end |
#convert_to_constant(value) ⇒ Object
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/cisco_node_utils/command_reference.rb', line 276 def convert_to_constant(value) # NOTE: This method is now deprecated and should not be used for future # development. # # If value is a string and it is empty OR the first letter is lower case # then leave value untouched. # If value is a string and the first letter is uppercase this indicates # that it could be a constant in Ruby, so attempt to convert it # to a Constant. if value.is_a?(String) && !value.empty? if value[0].chr == value[0].chr.upcase begin value = Object.const_get(value) if Object.const_defined?(value) rescue NameError debug("'#{value}' is not a constant") end end end value end |
#define_helper(method_name, base_hash) ⇒ Object
Create a helper method for generating the getter/setter values. This method will automatically handle wildcard arguments.
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/cisco_node_utils/command_reference.rb', line 179 def define_helper(method_name, base_hash) # Which kind of wildcards (if any) do we need to support? combined = [] base_hash.each_value do |v| combined += v if v.is_a?(Array) combined << v if v.is_a?(String) end key_value = combined.any? { |i| i.is_a?(String) && /<\S+>/ =~ i } printf = combined.any? { |i| i.is_a?(String) && /%/ =~ i } if key_value && printf fail 'Invalid mixture of key-value and printf wildcards ' \ "in #{method_name}: #{combined}" elsif key_value define_key_value_helper(method_name, base_hash) elsif printf arg_count = combined.join.scan(/%/).length define_printf_helper(method_name, base_hash, arg_count) else # simple static token(s) define_static_helper(method_name, base_hash) end @hash[method_name] = true end |
#define_key_value_helper(method_name, base_hash) ⇒ Object
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/cisco_node_utils/command_reference.rb', line 204 def define_key_value_helper(method_name, base_hash) # Key-value substitution define_singleton_method method_name.to_sym do |*args, **kwargs| unless args.empty? fail ArgumentError, "#{method_name} requires keyword args, not "\ 'positional args' end result = {} base_hash.each do |k, v| if v.is_a?(String) v = key_substitutor(v, kwargs) elsif v.is_a?(Array) output = [] v.each do |line| # Check for (?) flag indicating optional param optional_line = line[/^\(\?\)(.*)/, 1] if optional_line begin line = key_substitutor(optional_line, kwargs) rescue ArgumentError # Unsubstituted key - OK to skip this line next end else line = key_substitutor(line, kwargs) end output.push(line) end v = output end result[k] = v end result end end |
#define_printf_helper(method_name, base_hash, arg_count) ⇒ Object
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/cisco_node_utils/command_reference.rb', line 239 def define_printf_helper(method_name, base_hash, arg_count) define_singleton_method method_name.to_sym do |*args, **kwargs| unless kwargs.empty? fail ArgumentError, "#{method_name} requires positional args, not " \ 'keyword args' end unless args.length == arg_count fail ArgumentError, 'wrong number of arguments ' \ "(#{args.length} for #{arg_count})" end result = {} base_hash.each do |k, v| if v.is_a?(String) v, args = printf_substitutor(v, args) elsif v.is_a?(Array) output = [] v.each do |line| line, args = printf_substitutor(line, args) output.push(line) end v = output end result[k] = v end result end end |
#define_static_helper(method_name, base_hash) ⇒ Object
268 269 270 271 272 273 274 |
# File 'lib/cisco_node_utils/command_reference.rb', line 268 def define_static_helper(method_name, base_hash) # rubocop:disable Lint/UnusedBlockArgument define_singleton_method method_name.to_sym do |*args, **kwargs| base_hash end # rubocop:enable Lint/UnusedBlockArgument end |
#getter(*args, **kwargs) ⇒ Object
Default getter method. Will be overridden at initialization if the relevant parameters are set.
A non-trivial implementation of this method will take args or kwargs, and will return a hash of the form:
data_format: :cli,
command: string or nil,
context: array<string> or array<regexp>, perhaps empty
value: string or regexp,
138 139 140 |
# File 'lib/cisco_node_utils/command_reference.rb', line 138 def getter(*args, **kwargs) # rubocop:disable Lint/UnusedMethodArgument fail UnsupportedError.new(@feature, @name, 'getter') end |
#getter? ⇒ Boolean
Does this instance have a valid getter() function? Will be overridden at initialization if so.
117 118 119 |
# File 'lib/cisco_node_utils/command_reference.rb', line 117 def getter? !@hash['getter'].nil? end |
#key_substitutor(item, kwargs) ⇒ Object
161 162 163 164 165 166 167 168 169 170 |
# File 'lib/cisco_node_utils/command_reference.rb', line 161 def key_substitutor(item, kwargs) result = item kwargs.each do |key, value| result = result.sub("<#{key}>", value.to_s) end unsub = result[/<(\S+)>/, 1] fail ArgumentError, \ "No value specified for '#{unsub}' in '#{result}'" if unsub result end |
#printf_substitutor(item, args) ⇒ Object
172 173 174 175 |
# File 'lib/cisco_node_utils/command_reference.rb', line 172 def printf_substitutor(item, args) item = sprintf(item, *args.shift(item.scan(/%/).length)) [item, args] end |
#setter(*args, **kwargs) ⇒ Object
Default setter method. Will be overridden at initialization if the relevant parameters are set.
A non-trivial implementation of this method will take args or kwargs, and will return a hash of the form:
data_format: :cli,
context: array<string>, perhaps empty
values: array<string>,
152 153 154 |
# File 'lib/cisco_node_utils/command_reference.rb', line 152 def setter(*args, **kwargs) # rubocop:disable Lint/UnusedMethodArgument fail UnsupportedError.new(@feature, @name, 'setter') end |
#setter? ⇒ Boolean
Does this instance have a valid setter() function? Will be overridden at initialization if so.
123 124 125 |
# File 'lib/cisco_node_utils/command_reference.rb', line 123 def setter? !@hash['setter'].nil? end |
#to_s ⇒ Object
Print useful debugging information about the object.
320 321 322 323 324 325 |
# File 'lib/cisco_node_utils/command_reference.rb', line 320 def to_s str = '' str << "Command: #{@feature} #{@name}\n" @hash.each { |key, value| str << " #{key}: #{value}\n" } str end |
#values_to_hash(values, file) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/cisco_node_utils/command_reference.rb', line 69 def values_to_hash(values, file) @hash = {} values.each do |key, value| unless KEYS.include?(key) fail "Unrecognized key #{key} for #{feature}, #{name} in #{file}" end case key when 'auto_default' @auto_default = value ? true : false when 'data_format', 'get_data_format', 'set_data_format' @hash[key] = value.to_sym when 'default_only' @default_only = true # default_value overrides default_only @hash['default_value'] ||= value when 'multiple' @multiple = boolean_default_true(value) when 'kind' fail "Unknown 'kind': '#{value}'" unless KINDS.include?(value) @kind = value.to_sym else # default_value overrides default_only @default_only = false if key == 'default_value' @hash[key] = value end end # Inherit general to specific if needed if @hash.key?('data_format') @hash['get_data_format'] = @hash['data_format'] \ unless @hash.key?('get_data_format') @hash['set_data_format'] = @hash['data_format'] \ unless @hash.key?('set_data_format') end if @hash.key?('context') @hash['get_context'] = @hash['context'] unless @hash.key?('get_context') @hash['set_context'] = @hash['context'] unless @hash.key?('set_context') end if @hash.key?('value') @hash['get_value'] = @hash['value'] unless @hash.key?('get_value') @hash['set_value'] = @hash['value'] unless @hash.key?('set_value') end @hash.delete_if { |key, _| key != 'default_value' } if @default_only end |