class Measurb::DimensionBuilder
Factory class for building new dimension classes
Attributes
Public Class Methods
Get an appropriate class name for a dimension name
@param name [Symbol, String] Name of the dimension @return [String] Name of the dimension class
# File lib/measurb/dimension_builder.rb, line 10 def self.get_dimension_class_name(name) name.to_s.split('_').map(&:capitalize).join end
Initialize the builder
@param name [Symbol, String] Name of the dimension @param options [Hash] @option options [String] :abbrev (nil) The dimension abbreviation @param block [Proc] Block for defining conversions to other dimensions
# File lib/measurb/dimension_builder.rb, line 20 def initialize(name, options = {}, &block) @name = name @def_block = block @options = options @dimension_class_name = self.class.get_dimension_class_name(name) end
Public Instance Methods
@!attribute [r] dimension_class
Get the dimension class, creating it if it's not available @return [Measurb::Dimension]
# File lib/measurb/dimension_builder.rb, line 30 def dimension_class build_dimension_class unless defined?(@dimension_class) @dimension_class end
Use to build conversion methods to other dimensions
# File lib/measurb/dimension_builder.rb, line 36 def method_missing(name, *args, &block) build_default_conversion(name, args.first) end
Private Instance Methods
Build a conversion method, using `block` as the body
@param name [Symbol, String] Name of the dimension @param block [Proc] Conversion method body
# File lib/measurb/dimension_builder.rb, line 59 def build_conversion(name, &block) @dimension_class.__send__(:define_method, "to_#{name}", &block) end
Build a conversion to another dimension with a default implementation
@param name [Symbol, String] Name of the dimension @param conversion [Proc] Proc to convert the actual value
# File lib/measurb/dimension_builder.rb, line 46 def build_default_conversion(name, conversion) class_name = self.class.get_dimension_class_name(name) build_conversion(name) do precision ||= self.precision Measurb.const_get(class_name).new(instance_eval(&conversion), precision) end end
Build the dimension class, defining any conversions from `@def_block` and defining a default conversion to itself
# File lib/measurb/dimension_builder.rb, line 65 def build_dimension_class @value = ValueProxy.new @dimension_class = Class.new(Dimension) @dimension_class.instance_variable_set(:@dimension_name, @name.to_s) @dimension_class.instance_variable_set(:@abbrev, @options[:abbrev]) instance_eval(&@def_block) unless @def_block.nil? # Return self when converting to same dimension build_conversion(@name) { self } end