better_struct 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
- metadata.gz: 97a1b4ed42f6ff0493a116d85f4126719ef77483
4
- data.tar.gz: f074b953c21dbc3f369980fda77cba90a97d4f9c
3
+ metadata.gz: 63739e5a654591d3d685a383a163fca50902f3b2
4
+ data.tar.gz: 8ac3510abea38370cbe2d67a951deec7d1c002bd
5
5
  SHA512:
6
- metadata.gz: 47f5073d2d96c0dafa123fd270fc134f7e5cb8c4db66ed6cd8b87ef54052f5f8213198f515f3b0816f390f60257e9d51790137c2e4d0d47f222826354dbf4ef2
7
- data.tar.gz: e40dfdbb67e4f26060550cd009da3e9e079e102fbeabeeb2fadeb3ab5bb18e17ea364c65f84ca9a6bb80b5b9699530930ab7a0653f1cbdbe6b5c556461892fa6
6
+ metadata.gz: 45b9c991c3010cfd5ce2b25a853bbffd2f0bef51b6479770571141b8b293b01ceef9ab93102d6054e14a91aae4715b1172768afd37791d0a0d4130d457dc9b76
7
+ data.tar.gz: 03f58914d44f74f1d4a2eafb045066b338723f13e603fa32af51f9555aec93ecc1097d1c4aab056d3c7f1803a75807ebc1fef0d3651a10f2fb49661bbb9d0363
data/README.md CHANGED
@@ -10,12 +10,12 @@ It behaves like an OpenStruct on steroids with monad.
10
10
  hash = { "FooBar1" => { foo_bar2: "Hello World!" } }
11
11
 
12
12
  # Instead of this:
13
- if hash["FooBar1"] && hash["FooBar1"][:foo_bar2]
14
- puts hash["FooBar1"][:foo_bar2]
13
+ if hash["FooBar1"] && hash["FooBar1"][:foo_bar2] && hash["FooBar1"][:foo_bar2].respond_to?(:sub)
14
+ hash["FooBar1"][:foo_bar2].sub("Hello ", "") # => "World!"
15
15
  end
16
16
 
17
17
  # Simply use:
18
- puts BetterStruct.new(hash).foo_bar1.foo_bar2.value
18
+ BetterStruct.new(hash).foo_bar1.foo_bar2.sub("Hello ", "").value # => "World!"
19
19
  ```
20
20
 
21
21
  ## Installation
@@ -39,7 +39,7 @@ Or install it yourself as:
39
39
  #### Maybe monad
40
40
 
41
41
  ```ruby
42
- BetterStruct.new(nil) == BetterStruct.new(nil).some_method # => true
42
+ BetterStruct.new(nil) == BetterStruct.new(nil).this_method.does_not_exist # => true
43
43
  ```
44
44
 
45
45
  #### Everything is wrapped
@@ -47,21 +47,16 @@ BetterStruct.new(nil) == BetterStruct.new(nil).some_method # => true
47
47
  ```ruby
48
48
  better_struct = BetterStruct.new("foobar")
49
49
 
50
- better_struct[0..2].is_a?(BetterStruct) # => true
51
50
  better_struct[0..2] == BetterStruct.new("foo") # => true
52
51
  ```
53
52
 
54
53
  ```ruby
55
54
  better_struct = BetterStruct.new([1, 2, 3])
56
55
 
57
- result = better_struct.all? { |i| i.is_a?(BetterStruct) }
58
-
59
- result.is_a?(BetterStruct) # => true
60
- result == BetterStruct.new(true) # => true
61
-
56
+ better_struct.all? { |i| i.is_a?(BetterStruct) } == BetterStruct.new(true) # => true
62
57
  ```
63
58
 
64
- #### Like OpenStruct
59
+ #### Like an OpenStruct on steroids
65
60
 
66
61
  ```ruby
67
62
  some_hash = { "FooBar1" => { foo_bar2: "Hello World!" } }
@@ -85,21 +80,21 @@ better_struct.gsub("foo", "super-").value == "super-foo" # => true
85
80
 
86
81
  ## Benchmarking
87
82
 
88
- It is as fast as an OpenStruct:
83
+ **BetterStruct** is even faster than an OpenStruct:
89
84
 
90
85
  ```
91
86
  $ ruby scripts/benchmark.rb
92
87
 
93
88
  Calculating -------------------------------------
94
- OpenStruct 6.562k i/100ms
95
- BetterStruct 7.155k i/100ms
89
+ OpenStruct 7.334k i/100ms
90
+ BetterStruct 7.856k i/100ms
96
91
  -------------------------------------------------
97
- OpenStruct 75.194k (± 7.4%) i/s - 374.034k
98
- BetterStruct 76.987k6.7%) i/s - 386.370k
92
+ OpenStruct 75.971k (± 7.1%) i/s - 381.368k
93
+ BetterStruct 84.520k4.5%) i/s - 424.224k
99
94
 
100
95
  Comparison:
101
- BetterStruct: 76986.7 i/s
102
- OpenStruct: 75193.6 i/s - 1.02x slower
96
+ BetterStruct: 84519.8 i/s
97
+ OpenStruct: 75971.1 i/s - 1.11x slower
103
98
  ```
104
99
 
105
100
  ## Contributing
@@ -18,8 +18,6 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency "activesupport", ">= 3.2.0"
22
-
23
21
  spec.add_development_dependency "bundler", "~> 1.7"
24
22
  spec.add_development_dependency "rake", "~> 10.0"
25
23
  spec.add_development_dependency "minitest", "~> 5.5"
@@ -1,8 +1,8 @@
1
- require "better_struct/version"
2
- require "active_support/inflector"
1
+ require "set"
2
+ require_relative "./better_struct/version"
3
+ require_relative "./better_struct/methodize"
3
4
 
4
5
  class BetterStruct
5
- PARAMETERIZE_SEPARATOR = "_".freeze
6
6
  EQUAL_SIGN = "=".freeze
7
7
  MAP_METHOD_NAMES = %i(map map!).to_set.freeze
8
8
 
@@ -26,21 +26,11 @@ class BetterStruct
26
26
 
27
27
  private
28
28
 
29
- def methodize(string)
30
- result = ActiveSupport::Inflector.underscore(string)
31
-
32
- if result =~ /[^\w]/
33
- ActiveSupport::Inflector.parameterize(result, PARAMETERIZE_SEPARATOR)
34
- else
35
- result
36
- end
37
- end
38
-
39
29
  def wrap(value)
40
30
  value.is_a?(self.class) ? self : self.class.new(value)
41
31
  end
42
32
 
43
- def wrap_block_args(*args, &block)
33
+ def wrap_block_args(&block)
44
34
  return if block.nil?
45
35
 
46
36
  Proc.new do |*args|
@@ -52,16 +42,15 @@ private
52
42
  def method_missing(method_name, *args, &block)
53
43
  if value.respond_to?(method_name)
54
44
  delegate_method(method_name, *args, &block)
55
- elsif assignment?(method_name, *args, &block) && defined_methods
56
- attribute = methodize(method_name[0...-1])
57
- @defined_methods[attribute] = args.first
45
+ elsif assignment?(method_name) && defined_methods
46
+ @defined_methods[methodize(method_name[0...-1])] = args.first
58
47
  else
59
48
  wrap(defined_methods[method_name.to_s])
60
49
  end
61
50
  end
62
51
 
63
- def assignment?(method_name, *args, &block)
64
- method_name[-1] == EQUAL_SIGN && args.size == 1 && block.nil?
52
+ def assignment?(method_name)
53
+ method_name[-1] == EQUAL_SIGN
65
54
  end
66
55
 
67
56
  def defined_methods
@@ -77,12 +66,12 @@ private
77
66
  end
78
67
 
79
68
  def delegate_method(method_name, *args, &block)
80
- result = wrap(value.public_send(method_name, *unwrap_items(args), &wrap_block_args(*args, &block)))
69
+ result = value.public_send(method_name, *unwrap_items(args), &wrap_block_args(&block))
81
70
 
82
71
  if MAP_METHOD_NAMES.include?(method_name)
83
- wrap(unwrap_items(result.value))
72
+ wrap(unwrap_items(result))
84
73
  else
85
- result
74
+ wrap(result)
86
75
  end
87
76
  end
88
77
 
@@ -0,0 +1,46 @@
1
+ class BetterStruct
2
+ EMPTY_STRING = "".freeze
3
+ UNDERSCORE_SIGN = "_".freeze
4
+
5
+ TRANSLITERATION_FROM = "ÀÁÂÃÄÅàáâãäåĀāĂ㥹ÇçĆćĈĉĊċČčÐðĎďĐđÈÉÊËèéêëĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħÌÍÎÏìíîïĨĩĪīĬĭĮįİıĴĵĶķĸĹĺĻļĽľĿŀŁłÑñŃńŅņŇňʼnŊŋÒÓÔÕÖØòóôõöøŌōŎŏŐőŔŕŖŗŘřŚśŜŝŞşŠšſŢţŤťŦŧÙÚÛÜùúûüŨũŪūŬŭŮůŰűŲųŴŵÝýÿŶŷŸŹźŻżŽž".freeze
6
+ TRANSLITERATION_TO = "AAAAAAaaaaaaAaAaAaCcCcCcCcCcDdDdDdEEEEeeeeEeEeEeEeEeGgGgGgGgHhHhIIIIiiiiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnNnnNnOOOOOOooooooOoOoOoRrRrRrSsSsSsSssTtTtTtUUUUuuuuUuUuUuUuUuUuWwYyyYyYZzZzZz".freeze
7
+
8
+ UPCASE_REGEXP = /[A-Z]/.freeze
9
+ NOT_UNDERSCORED_REGEXP = /[^a-z0-9_]/.freeze
10
+ NON_ENGLISH_REGEXP = /[#{ TRANSLITERATION_FROM }]/.freeze
11
+ UNDERSCORE_DUPLICATES_REGEXP = /#{ UNDERSCORE_SIGN }{2,}/.freeze
12
+ UNDERSCORE_BEGIN_OR_END_REGEXP = /^#{ UNDERSCORE_SIGN }|#{ UNDERSCORE_SIGN }$/.freeze
13
+ CAMELCASE_ABBREVIATION_REGEX = /([A-Z\d]+)([A-Z][a-z])/.freeze
14
+ CAMELCASE_REGEX = /([a-z\d])([A-Z])/.freeze
15
+
16
+ UNDERSCORE_MASK = '\1_\2'.freeze
17
+
18
+ private
19
+
20
+ def methodize(string)
21
+ return string unless string =~ NOT_UNDERSCORED_REGEXP
22
+
23
+ string = string.dup
24
+
25
+ transliterate!(string)
26
+ underscore!(string)
27
+ string
28
+ end
29
+
30
+ def transliterate!(string)
31
+ if string =~ NON_ENGLISH_REGEXP
32
+ string.tr!(TRANSLITERATION_FROM, TRANSLITERATION_TO)
33
+ end
34
+ end
35
+
36
+ def underscore!(string)
37
+ if string =~ NOT_UNDERSCORED_REGEXP
38
+ string.gsub!(CAMELCASE_ABBREVIATION_REGEX, UNDERSCORE_MASK)
39
+ string.gsub!(CAMELCASE_REGEX, UNDERSCORE_MASK)
40
+ string.downcase!
41
+ string.gsub!(NOT_UNDERSCORED_REGEXP, UNDERSCORE_SIGN)
42
+ string.gsub!(UNDERSCORE_DUPLICATES_REGEXP, UNDERSCORE_SIGN)
43
+ string.gsub!(UNDERSCORE_BEGIN_OR_END_REGEXP, EMPTY_STRING)
44
+ end
45
+ end
46
+ end
@@ -1,3 +1,3 @@
1
1
  class BetterStruct
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1".freeze
3
3
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: better_struct
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evgeny Li
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-27 00:00:00.000000000 Z
11
+ date: 2015-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: activesupport
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ! '>='
18
- - !ruby/object:Gem::Version
19
- version: 3.2.0
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ! '>='
25
- - !ruby/object:Gem::Version
26
- version: 3.2.0
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: bundler
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +108,7 @@ files:
122
108
  - Rakefile
123
109
  - better_struct.gemspec
124
110
  - lib/better_struct.rb
111
+ - lib/better_struct/methodize.rb
125
112
  - lib/better_struct/version.rb
126
113
  - test/better_struct_test.rb
127
114
  homepage: https://github.com/exAspArk/better_struct