Class: Shippo::API::Category::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/shippo/api/category/base.rb

Overview

Base is a convenience abstract class that provides the following functionality to it’s subclasses, which are meant to be enumerations with a fixed number of possible values.

Base populates a global hash Shippo::API::Category.categories which is keyed by the lower cased and symbolized category name (eg, :status or :purpose), each value is another hash consisting of keys (values of each category, eg :success, :error) and value being the constant created for such a value.

__WARNING__: You are not supposed to instantiate these classes, to be honest. The “correct” way is via the Facåde Shippo::API::Category.for(name, value).

Example

“‘ruby require ’shippo/api’ class Size < ::Shippo::API::Category::Base

allowed_values :small, :medium, :large, :xlarge, :xxlarge

end # ⤷ [:small, :medium, :large, :xlarge, :xxlarge]

my_size = Shippo::API::Category.for(‘size’, ‘xlarge’) # ⤷ size:xlarge

my_size.xlarge? # ⤷ true my_size.medium? # ⤷ false my_size.name # ⤷ size my_size.value # ⤷ xlarge

medium_1 = Size.new(‘medium’)

 size:medium

medium_2 = Size.new(‘medium’)

 size:medium

medium_3 = Shippo::API::Category.for(:size, :medium)

 size:medium

# But keep in mind these instances are all different objects, # which are eql?() to each other, but not identical. medium_1.object_id # ⤷ 70282669124280 medium_2.object_id # ⤷ 70282669580500 medium_3.object_id # ⤷ 70282681963740 medium_1.eql?(medium_2) # ⤷ true medium_2.eql?(medium_3) # ⤷ true “‘

Direct Known Subclasses

Purpose, Source, State, Status

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value) ⇒ Base

Returns a new instance of Base.



105
106
107
108
109
# File 'lib/shippo/api/category/base.rb', line 105

def initialize(value)
  raise ::Shippo::Exceptions::AbstractClassInitError.new('Can not instantiate Base!') if self.class.eql?(::Shippo::API::Category::Base)
  self.name = Category.key(self.class.name.gsub(%r{.*::}, ''))
  self.value = assign_value(value)
end

Class Attribute Details

.categoriesObject

Returns the value of attribute categories.



62
63
64
# File 'lib/shippo/api/category/base.rb', line 62

def categories
  @categories
end

Instance Attribute Details

#nameObject

Returns the value of attribute name.



103
104
105
# File 'lib/shippo/api/category/base.rb', line 103

def name
  @name
end

#valueObject

Returns the value of attribute value.



103
104
105
# File 'lib/shippo/api/category/base.rb', line 103

def value
  @value
end

Class Method Details

.inherited(klazz) ⇒ Object



65
66
67
68
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
# File 'lib/shippo/api/category/base.rb', line 65

def self.inherited(klazz)
  klazz.instance_eval do
    @allowed_values = Set.new
    class << self
      def categories
        ::Shippo::API::Category::Base.categories
      end

      def value_transformer(values)
        values.map(&:downcase).map(&:to_sym)
      end

      def allowed_values(*values)
        return @allowed_values if values.nil? || values.empty? || !@allowed_values.empty?

        @allowed_values = self.value_transformer(values)
        @allowed_values.each do |allowed_value|
          category_value = Category.key(allowed_value)
          category_const = category_value.to_s.upcase

          raise ::Shippo::API::Category::DuplicateValueError.new(
            "Constant #{category_const} is already defined in #{self.name}") if self.const_defined?(category_const)

          new_instance = self.new(category_value)
          self.const_set(category_const, new_instance)

          define_method "#{category_value}?".to_sym do
            value.eql?(category_value)
          end

          categories[new_instance.name]                     ||= {}
          categories[new_instance.name][new_instance.value] = new_instance
        end
      end
    end
  end
end

Instance Method Details

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/shippo/api/category/base.rb', line 111

def eql?(other)
  self.class.eql?(other.class) && self.value.eql?(other.value)
end

#to_sObject



115
116
117
# File 'lib/shippo/api/category/base.rb', line 115

def to_s
  "#{self.value.upcase}"
end