Skip to content

Commit 35f1d9b

Browse files
committed
Performance improvements for ValueHelper
- Put more common types higher up the if-else clause - Use a constant regex instead of creating a new one on every call - Avoid calling .to_s.downcase repeatedly: - Extract into single `#to_s` call - Let regex match in case-insensitive mode
1 parent da410a5 commit 35f1d9b

3 files changed

Lines changed: 36 additions & 32 deletions

File tree

lib/class_kit.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require_relative 'class_kit/constants'
12
require_relative 'class_kit/class_methods'
23
require_relative 'class_kit/exceptions'
34
require_relative 'class_kit/attribute_helper'
@@ -10,4 +11,3 @@
1011
require 'date'
1112
require 'bigdecimal'
1213
require 'time'
13-

lib/class_kit/constants.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# frozen_string_literal: true
2+
3+
module ClassKit
4+
module Constants
5+
# Shared constants, to avoid re-creating them on each call to helper methods.
6+
BOOL_TRUE_RE = /\A(?:true|t|yes|y|1)\z/i
7+
BOOL_FALSE_RE = /\A(?:false|f|no|n|0)\z/i
8+
end
9+
end

lib/class_kit/value_helper.rb

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,19 @@
11
module ClassKit
22
class ValueHelper
3-
43
def self.instance
54
@@instance ||= new
65
end
76

87
def parse(type:, value:)
9-
if type == Time
10-
if value.is_a?(Time)
11-
value
12-
elsif value.is_a?(Integer) || value.is_a?(Float) || value.is_a?(BigDecimal)
13-
Time.at(value)
14-
else
15-
Time.parse(value)
16-
end
17-
elsif type == Date
18-
if value.is_a?(Date)
19-
value
20-
else
21-
Date.parse(value)
22-
end
23-
elsif type == DateTime
24-
if value.is_a?(DateTime)
25-
value
26-
else
27-
DateTime.parse(value)
28-
end
29-
elsif type == :bool
30-
if value == true || value == false
31-
value
32-
elsif(/(true|t|yes|y|1)$/i === value.to_s.downcase)
8+
if type == :bool
9+
return value if value == true || value == false
10+
11+
s = value.to_s
12+
if Constants::BOOL_TRUE_RE.match?(s)
3313
true
34-
elsif (/(false|f|no|n|0)$/i === value.to_s.downcase)
14+
elsif Constants::BOOL_FALSE_RE.match?(s)
3515
false
36-
elsif value != nil
16+
elsif !value.nil?
3717
raise 'Unable to parse bool'
3818
end
3919
elsif type == Integer
@@ -44,26 +24,41 @@ def parse(type:, value:)
4424
if value.is_a?(BigDecimal)
4525
value
4626
else
47-
value = value.to_s
48-
raise 'Unable to parse BigDecimal' unless value =~ /\A-?\d+(\.\d*)?/
49-
BigDecimal(value)
27+
s = value.to_s
28+
raise 'Unable to parse BigDecimal' unless s =~ /\A-?\d+(\.\d*)?/
29+
30+
BigDecimal(s)
5031
end
5132
elsif type == String
5233
String(value)
34+
elsif type == Time
35+
if value.is_a?(Time)
36+
value
37+
elsif value.is_a?(Integer) || value.is_a?(Float) || value.is_a?(BigDecimal)
38+
Time.at(value)
39+
else
40+
Time.parse(value)
41+
end
42+
elsif type == Date
43+
value.is_a?(Date) ? value : Date.parse(value)
44+
elsif type == DateTime
45+
value.is_a?(DateTime) ? value : DateTime.parse(value)
5346
elsif type == Regexp
5447
Regexp.new(value)
5548
elsif type == Hash
5649
raise 'Unable to parse Hash' unless value.is_a?(Hash)
50+
5751
value
5852
elsif type == Array
5953
raise 'Unable to parse Array' unless value.is_a?(Array)
54+
6055
value
6156
elsif type.include?(ClassKit::CustomType)
6257
type.parse_assign(value)
6358
else
6459
raise 'Unable to parse'
6560
end
66-
rescue => e
61+
rescue StandardError => e
6762
raise ClassKit::Exceptions::InvalidParseValueError,
6863
"Unable to parse value: #{value} into type: #{type}. Error: #{e}"
6964
end

0 commit comments

Comments
 (0)