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 config_set config_set_append config_get config_get_token config_get_token_append auto_default multiple kind test_config_get test_config_get_regex test_config_result)
- KINDS =
%w(boolean int string)
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_getter(key, value) ⇒ Object
Create a getter method for the given key.
-
#initialize(feature, name, values, file) ⇒ CmdRef
constructor
Construct a CmdRef describing the given (feature, name) pair.
-
#key_substitutor(config_key, value) ⇒ Object
curried function to define a getter method body that performs key-value substitution.
- #method_missing(method_name, *args, &block) ⇒ Object
-
#preprocess_value(value) ⇒ Object
Helper method.
-
#printf_substitutor(config_key, value) ⇒ Object
curried function to define a getter method body that performs printf-style substitution.
- #test_config_result(value) ⇒ Object
-
#to_s ⇒ Object
Print useful debugging information about the 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.
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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/cisco_node_utils/command_reference.rb', line 43 def initialize(feature, name, values, file) fail ArgumentError, "'#{values}' is not a hash." unless values.is_a? Hash @feature = feature @name = name @hash = {} @auto_default = true @default_only = false @multiple = false @kind = nil values.each do |key, value| unless KEYS.include?(key) fail "Unrecognized key #{key} for #{feature}, #{name} in #{file}" end if key == 'config_get_token' || key == 'config_set' # For simplicity, these are ALWAYS arrays value = [value] unless value.is_a?(Array) define_getter(key, value) # We intentionally do this *after* the define_getter() call @hash[key] = preprocess_value(value) elsif key == 'auto_default' @auto_default = value ? true : false elsif key == 'default_only' @default_only = true # default_value overrides default_only @hash['default_value'] ||= preprocess_value(value) elsif key == 'multiple' @multiple = boolean_default_true(value) elsif key == '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] = preprocess_value(value) end end if @default_only # rubocop:disable Style/GuardClause %w(config_get_token config_set).each do |key| instance_eval "undef #{key}" if @hash.key?(key) end @hash.delete_if { |key, _| key != 'default_value' } end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args, &block) ⇒ Object
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/cisco_node_utils/command_reference.rb', line 195 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.
23 24 25 |
# File 'lib/cisco_node_utils/command_reference.rb', line 23 def auto_default @auto_default end |
#default_only ⇒ Object (readonly) Also known as: default_only?
Returns the value of attribute default_only.
23 24 25 |
# File 'lib/cisco_node_utils/command_reference.rb', line 23 def default_only @default_only end |
#feature ⇒ Object (readonly)
Returns the value of attribute feature.
22 23 24 |
# File 'lib/cisco_node_utils/command_reference.rb', line 22 def feature @feature end |
#hash ⇒ Object (readonly)
Returns the value of attribute hash.
22 23 24 |
# File 'lib/cisco_node_utils/command_reference.rb', line 22 def hash @hash end |
#kind ⇒ Object (readonly)
Returns the value of attribute kind.
23 24 25 |
# File 'lib/cisco_node_utils/command_reference.rb', line 23 def kind @kind end |
#multiple ⇒ Object (readonly) Also known as: multiple?
Returns the value of attribute multiple.
23 24 25 |
# File 'lib/cisco_node_utils/command_reference.rb', line 23 def multiple @multiple end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
22 23 24 |
# File 'lib/cisco_node_utils/command_reference.rb', line 22 def name @name end |
Class Method Details
.keys ⇒ Object
34 35 36 |
# File 'lib/cisco_node_utils/command_reference.rb', line 34 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
91 92 93 |
# File 'lib/cisco_node_utils/command_reference.rb', line 91 def boolean_default_true(value) value.nil? || value end |
#convert_to_constant(value) ⇒ Object
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/cisco_node_utils/command_reference.rb', line 169 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_getter(key, value) ⇒ Object
Create a getter method for the given key. This getter method will automatically handle wildcard arguments.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/cisco_node_utils/command_reference.rb', line 97 def define_getter(key, value) return unless value.is_a?(Array) if value.any? { |item| item.is_a?(String) && /<\S+>/ =~ item } # Key-value substitution define_singleton_method(key.to_sym, key_substitutor(key, value)) elsif value.any? { |item| item.is_a?(String) && /%/ =~ item } # printf-style substitution define_singleton_method(key.to_sym, printf_substitutor(key, value)) else # simple static token(s) value = preprocess_value(value) define_singleton_method key.to_sym, -> { value } end end |
#key_substitutor(config_key, value) ⇒ Object
curried function to define a getter method body that performs key-value substitution
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/cisco_node_utils/command_reference.rb', line 114 def key_substitutor(config_key, value) lambda do |**args| result = [] value.each do |line| replace = line.scan(/<(\S+)>/).flatten.map(&:to_sym) replace.each do |item| line = line.sub("<#{item}>", args[item].to_s) if args.key?(item) end result.push(line) unless /<\S+>/.match(line) end if result.empty? fail ArgumentError, "Arguments given to #{config_key} yield empty result" end preprocess_value(result) end end |
#preprocess_value(value) ⇒ Object
Helper method. Converts a regexp-like string (or array thereof) into a proper Regexp object (or array thereof)
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/cisco_node_utils/command_reference.rb', line 152 def preprocess_value(value) if value.is_a?(Array) # Recurse! return value.map { |item| preprocess_value(item) } elsif value.is_a?(String) # Some 'Strings' in YAML are actually intended to be regexps if value[0] == '/' && value[-1] == '/' # '/foo/' => %r{foo} return Regexp.new(value[1..-2]) elsif value[0] == '/' && value[-2..-1] == '/i' # '/foo/i' => %r{foo}i return Regexp.new(value[1..-3], Regexp::IGNORECASE) end end value end |
#printf_substitutor(config_key, value) ⇒ Object
curried function to define a getter method body that performs printf-style substitution
134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/cisco_node_utils/command_reference.rb', line 134 def printf_substitutor(config_key, value) arg_c = value.join.scan(/%/).length lambda do |*args| unless args.length == arg_c fail ArgumentError, "Given #{args.length} args, but #{config_key} requires #{arg_c}" end # Fill in the parameters result = value.map do |line| sprintf(line, *args.shift(line.scan(/%/).length)) end preprocess_value(result) end end |
#test_config_result(value) ⇒ Object
190 191 192 193 |
# File 'lib/cisco_node_utils/command_reference.rb', line 190 def test_config_result(value) result = @hash['test_config_result'][value] convert_to_constant(result) end |
#to_s ⇒ Object
Print useful debugging information about the object.
218 219 220 221 222 223 |
# File 'lib/cisco_node_utils/command_reference.rb', line 218 def to_s str = '' str << "Command: #{@feature} #{@name}\n" @hash.each { |key, value| str << " #{key}: #{value}\n" } str end |