Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

5.14.0 #67

Merged
merged 3 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/unit_measurements/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ def configure
end

# The following requires load various components of the unit measurements library.
require "unit_measurements/extras/numeric_methods"

require "unit_measurements/configuration"
require "unit_measurements/cache"
require "unit_measurements/unit_group_builder"
Expand Down
81 changes: 81 additions & 0 deletions lib/unit_measurements/extras/numeric_methods.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# -*- encoding: utf-8 -*-
# -*- frozen_string_literal: true -*-
# -*- warn_indent: true -*-

module UnitMeasurements
# This module provides methods to define +Numeric+ extension methods for a list
# of units within a unit group. If units are empty, it defaults to defining
# methods for all units in the unit group.
#
# This module is included in the +Measurement+ class to allow defining numeric
# extension methods for specified units.
#
# @see Measurement
#
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 5.14.0
module NumericMethods
# @scope class
# Defines +Numeric+ extension methods for specified units within the unit
# group. If units are empty, it defaults to defining methods for all units
# within the unit group.
#
# @param [Array<String|Symbol>] units
# An array of units' names for which numeric methods need to be defined.
# If empty, methods will be defined for all units in the unit group.
#
# @return [Array<Unit>] An array of units for which methods are defined.
#
# @example Define numeric methods for metres, centimetres, and millimetres:
# UnitMeasurements::Length.define_numeric_methods("metres", :cm, :mm)
#
# @example Define numeric methods for all units in the unit group:
# UnitMeasurements::Length.define_numeric_methods
#
# @see #define_numeric_method_for
#
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 5.14.0
def define_numeric_methods(*units)
unit_group = self
units = units.empty? ? unit_group.units : units

units.inject([]) do |units, unit|
units << define_numeric_method_for(unit, unit_group)
end
end

private

# @private
# @scope class
# This method defines a numeric method for a specific unit within a unit group.
# The method is defined dynamically using +define_method+ and associates the
# unit with the numeric value.
#
# @param [String|Symbol|Unit] unit
# The unit for which the numeric method is defined.
# @param [UnitGroup] unit_group The unit group to which the unit belongs.
#
# @return [Unit] The unit instance for which the method was defined.
#
# @see #define_numeric_methods
#
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 5.14.0
def define_numeric_method_for(unit, unit_group)
shivam091 marked this conversation as resolved.
Show resolved Hide resolved
unit = unit.is_a?(Unit) ? unit : unit_group.unit_for!(unit)

unit.names.each do |method_name|
# Check if the name contains alphabetic characters
next unless method_name =~ /^[a-zA-Z]+$/

Numeric.define_method(method_name) do
unit_group.new(self, unit)
end
end

unit
end
end
end
3 changes: 3 additions & 0 deletions lib/unit_measurements/measurement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module UnitMeasurements
# @see Conversion
# @see Formatter
# @see Math
# @see NumericMethods
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
# @since 1.0.0
class Measurement
Expand All @@ -32,6 +33,8 @@ class Measurement
include Formatter
include Math

extend NumericMethods

# Regular expression to match conversion strings.
#
# @author {Harshal V. Ladhe}[https://shivam091.github.io/]
Expand Down
33 changes: 33 additions & 0 deletions spec/unit_measurements/extras/numeric_methods_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# -*- encoding: utf-8 -*-
# -*- frozen_string_literal: true -*-
# -*- warn_indent: true -*-

# spec/unit_measurements/extras/numeric_methods_spec.rb

RSpec.describe UnitMeasurements::NumericMethods do
let(:unit_group) { UnitMeasurements::Length }
let(:m) { unit_group.unit_for!(:m) }
let(:cm) { unit_group.unit_for!(:cm) }

context "when units are specified" do
it "defines extension methods for specified units" do
unit_group.define_numeric_methods("m", "cm")

expect(Numeric.method_defined?("m")).to be_truthy
expect(Numeric.method_defined?("cm")).to be_truthy

expect(1.cm).to be_instance_of(unit_group)
end
end

context "when units are specified" do
it "defines extension methods for all units within the unit group" do
unit_group.define_numeric_methods

expect(Numeric.method_defined?("ft")).to be_truthy
expect(Numeric.method_defined?("in")).to be_truthy

expect(1.ft).to be_instance_of(unit_group)
end
end
end