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 os_version)
- 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.
-
#os_version ⇒ Object
readonly
Returns the value of attribute os_version.
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 68 |
# 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 @os_version = 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
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 |
# File 'lib/cisco_node_utils/command_reference.rb', line 300 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 |
#os_version ⇒ Object (readonly)
Returns the value of attribute os_version.
22 23 24 |
# File 'lib/cisco_node_utils/command_reference.rb', line 22 def os_version @os_version 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
160 161 162 |
# File 'lib/cisco_node_utils/command_reference.rb', line 160 def boolean_default_true(value) value.nil? || value end |
#convert_to_constant(value) ⇒ Object
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/cisco_node_utils/command_reference.rb', line 279 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.
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/cisco_node_utils/command_reference.rb', line 182 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
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 238 239 240 |
# File 'lib/cisco_node_utils/command_reference.rb', line 207 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
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 267 268 269 |
# File 'lib/cisco_node_utils/command_reference.rb', line 242 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
271 272 273 274 275 276 277 |
# File 'lib/cisco_node_utils/command_reference.rb', line 271 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,
141 142 143 |
# File 'lib/cisco_node_utils/command_reference.rb', line 141 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.
120 121 122 |
# File 'lib/cisco_node_utils/command_reference.rb', line 120 def getter? !@hash['getter'].nil? end |
#key_substitutor(item, kwargs) ⇒ Object
164 165 166 167 168 169 170 171 172 173 |
# File 'lib/cisco_node_utils/command_reference.rb', line 164 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
175 176 177 178 |
# File 'lib/cisco_node_utils/command_reference.rb', line 175 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>,
155 156 157 |
# File 'lib/cisco_node_utils/command_reference.rb', line 155 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.
126 127 128 |
# File 'lib/cisco_node_utils/command_reference.rb', line 126 def setter? !@hash['setter'].nil? end |
#to_s ⇒ Object
Print useful debugging information about the object.
323 324 325 326 327 328 |
# File 'lib/cisco_node_utils/command_reference.rb', line 323 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
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 114 115 116 |
# File 'lib/cisco_node_utils/command_reference.rb', line 70 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 when 'os_version' @os_version = value 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 |