contextuable 0.2.0 → 0.3.0

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
  SHA1:
3
- metadata.gz: 8bd1b22c48cd964a9e88d7c24042a3a5237cf412
4
- data.tar.gz: 29c4996901db2aaa4a4ca98618ddb2a912b11281
3
+ metadata.gz: f078d3e26b5f6a206f595db13edf2eeed2149f00
4
+ data.tar.gz: 2bffb3821243b8b7617d4b782a8cb6dadfc3f519
5
5
  SHA512:
6
- metadata.gz: 7c766b2fb0e126589259d917cead49aaffbc31f97df7edb4ce649215ad50dc0b55ab9c2736b004a9096d8e1765c763ba0941298a1a07c79ff238da02b48a9999
7
- data.tar.gz: 71dabd1609822f5401b0a23f98bedeba540f737c834fb96d1779611609c575a0d69780c626c01d006611891ac2df5beb112a212d126bd378ac991d853d862bb9
6
+ metadata.gz: 95857c57a2be144c38be622a911b71f5e22e3d92c643a2d37961fbc9fe3e2640457ae602441d4c1790942139739a5902b1ca9f7e4a484115aa15a7ba607959fb
7
+ data.tar.gz: 1f4a390b7c957a89044b03ecb5509060c863111f774dd86c5ce63c7e6bae6ee2efe9b92d8c9f4146c31efd7db1a1b44e1a470c73a4dbf8de8d78e6dd92e0bc96
data/README.md CHANGED
@@ -71,6 +71,15 @@ i.not_permitted
71
71
 
72
72
  ### Building better Structs
73
73
 
74
+ **no_method_error**
75
+ ```ruby
76
+ class Example < Contextuable
77
+ no_method_error
78
+ end
79
+
80
+ Example.new(foo: :bar).hello # => Error: NoMethodError
81
+ ```
82
+
74
83
  **required**
75
84
  ```ruby
76
85
  class Example < Contextuable
@@ -0,0 +1,37 @@
1
+ class Contextuable
2
+ module ClassMethods
3
+
4
+ def settings
5
+ @settings ||= {}
6
+ end
7
+
8
+ def required(*names)
9
+ settings[:required] = names.map(&:to_sym)
10
+ end
11
+
12
+ def no_method_error(input = true)
13
+ settings[:no_method_error] = input
14
+ end
15
+
16
+ def open_struct_behavior(input = true)
17
+ settings[:no_method_error] = !input
18
+ end
19
+
20
+ def ensure_presence(*names)
21
+ settings[:presence_required] = names.map(&:to_sym)
22
+ end
23
+
24
+ def aliases(*names)
25
+ settings[:equivalents] ||= []
26
+ settings[:equivalents] << names.map(&:to_sym)
27
+ end
28
+
29
+ def defaults(hash)
30
+ settings[:defaults] = hash
31
+ end
32
+
33
+ def permit(*names)
34
+ settings[:permitted] = names.map(&:to_sym)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,92 @@
1
+ class Contextuable
2
+ module InstanceMethods
3
+ def initialize(hash = {})
4
+ check_input_errors(hash)
5
+ hash = hash.select{|k, v| _permitted.include?(k.to_sym) } if _only_permitted?
6
+ @attrs = _defaults.merge(hash)
7
+ attrs.each do |k, v|
8
+ define_contextuable_method(k, v)
9
+ end
10
+ end
11
+
12
+ def method_missing(name, *args, &block)
13
+ if ary = find_in_equivalents(name)
14
+ _from_equivalents(ary)
15
+ elsif name =~ /\A\w+=\z/
16
+ set_attribute_macro(name, *args, &block)
17
+ else
18
+ out = provided_macro(name)
19
+ return out[:out] if out
20
+ raise NoMethodError if _no_method_error
21
+ end
22
+ end
23
+
24
+ def find_in_equivalents(name)
25
+ found = nil
26
+ _equivalents.each do |ary|
27
+ found = ary if ary.include?(name.to_sym)
28
+ break if found
29
+ end
30
+ found
31
+ end
32
+
33
+ def _from_equivalents(ary)
34
+ out = nil
35
+ ary.each do |method|
36
+ out = attrs[method.to_sym]
37
+ break if out
38
+ end
39
+ out
40
+ end
41
+
42
+ def _only_permitted?
43
+ _permitted.any?
44
+ end
45
+
46
+ def _permitted
47
+ _get_config[:permitted] || []
48
+ end
49
+
50
+ def _equivalents
51
+ _get_config[:equivalents] || []
52
+ end
53
+
54
+ def _presence_required
55
+ _get_config[:presence_required] || []
56
+ end
57
+
58
+ def _no_method_error
59
+ !_get_config[:no_method_error] == false
60
+ end
61
+
62
+ def _defaults
63
+ _get_config[:defaults] || {}
64
+ end
65
+
66
+ def _required_args
67
+ _get_config[:required] || []
68
+ end
69
+
70
+ def _get_config
71
+ self.class.settings
72
+ end
73
+
74
+ def check_input_errors(hash)
75
+ unless hash.class <= Hash
76
+ fail WrongArgument, "[Contextuable ERROR]: `#{self.class}` expects to receive a `Hash` or and object having `Hash` as ancestor."
77
+ end
78
+
79
+ _required_args.map(&:to_sym).each do |r|
80
+ unless hash.keys.map(&:to_sym).include?(r)
81
+ fail RequiredFieldNotPresent, "[Contextuable ERROR]: `#{self.class}` expect to be initialized with `#{r}` as an attribute."
82
+ end
83
+ end
84
+
85
+ _presence_required.map(&:to_sym).each do |r|
86
+ if hash[r].nil?
87
+ fail PresenceRequired, "[Contextuable ERROR]: `#{self.class}` expects to receive an attribute named `#{r}` not beeing `nil`"
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
data/lib/contextuable.rb CHANGED
@@ -1,48 +1,33 @@
1
1
  class Contextuable
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
+ autoload :ClassMethods, 'contextuable/class_methods'
4
+ autoload :InstanceMethods, 'contextuable/instance_methods'
3
5
 
4
6
  class RequiredFieldNotPresent < ArgumentError; end
5
7
  class PresenceRequired < ArgumentError; end
6
8
  class WrongArgument < ArgumentError; end
7
9
 
8
- class << self
9
- def required(*names)
10
- @_required = names.map(&:to_sym)
11
- end
12
-
13
- def ensure_presence(*names)
14
- @_presence_required = names.map(&:to_sym)
15
- end
16
-
17
- def aliases(*names)
18
- @_equivalents ||= []
19
- @_equivalents << names.map(&:to_sym)
20
- end
21
-
22
- def defaults(hash)
23
- @_defaults = hash
24
- end
25
-
26
- def permit(*names)
27
- @_permitted = names.map(&:to_sym)
28
- end
10
+ def self.inherited(subclass)
11
+ subclass.extend ClassMethods
12
+ subclass.include InstanceMethods
29
13
  end
30
14
 
31
- attr_reader :args
32
- alias_method :to_h, :args
33
- alias_method :to_hash, :args
15
+ attr_reader :attrs
16
+ alias_method :to_h, :attrs
17
+ alias_method :to_hash, :attrs
34
18
 
35
19
  def initialize(hash = {})
36
- check_input_errors(hash)
37
- hash = hash.select{|k, v| _permitted.include?(k.to_sym) } if _only_permitted?
38
- @args = _defaults.merge(hash)
39
- args.each do |k, v|
20
+ unless hash.class <= Hash
21
+ fail WrongArgument, "[Contextuable ERROR]: `#{self.class}` expects to receive a `Hash` or and object having `Hash` as ancestor."
22
+ end
23
+ @attrs = hash
24
+ @attrs.each do |k, v|
40
25
  define_contextuable_method(k, v)
41
26
  end
42
27
  end
43
28
 
44
29
  def [](key)
45
- args[key]
30
+ attrs[key]
46
31
  end
47
32
 
48
33
  def []=(key, value)
@@ -50,90 +35,37 @@ class Contextuable
50
35
  end
51
36
 
52
37
  def method_missing(name, *args, &block)
53
- if ary = find_in_equivalents(name)
54
- _from_equivalents(ary)
55
- elsif name =~ /\A\w+=\z/
56
- value = args.first || block
57
- key = name.to_s.gsub('=', '').to_sym
58
- set_attribute(key, value)
38
+ if name =~ /\A\w+=\z/
39
+ set_attribute_macro(name, *args, &block)
59
40
  else
60
- case name.to_s
61
- when /\A\w+_not_provided\?\z/ then true
62
- when /\A\w+_provided\?\z/ then false
63
- end
41
+ out = provided_macro(name)
42
+ out ? out[:out] : nil
64
43
  end
65
44
  end
66
45
 
67
46
  private
68
47
 
69
- def set_attribute(key, value)
70
- args[key] = value
71
- define_contextuable_method(key, value)
72
- end
73
-
74
- def define_contextuable_method(key, value)
75
- define_singleton_method(key) { args.fetch(key) }
76
- define_singleton_method("#{key}_provided?") { true }
77
- define_singleton_method("#{key}_not_provided?") { false }
78
- end
79
-
80
- def find_in_equivalents(name)
81
- found = nil
82
- _equivalents.each do |ary|
83
- found = ary if ary.include?(name.to_sym)
84
- break if found
85
- end
86
- found
48
+ def set_attribute_macro(name, *args, &block)
49
+ value = args.first || block
50
+ key = name.to_s.gsub('=', '').to_sym
51
+ set_attribute(key, value)
87
52
  end
88
53
 
89
- def _from_equivalents(ary)
90
- out = nil
91
- ary.each do |method|
92
- out = args[method.to_sym]
93
- break if out
54
+ def provided_macro(name)
55
+ case name.to_s
56
+ when /\A\w+_not_provided\?\z/ then { out: true }
57
+ when /\A\w+_provided\?\z/ then { out: false }
94
58
  end
95
- out
96
59
  end
97
60
 
98
- def _only_permitted?
99
- _permitted.any?
100
- end
101
-
102
- def _permitted
103
- self.class.instance_variable_get(:@_permitted) || []
104
- end
105
-
106
- def _equivalents
107
- self.class.instance_variable_get(:@_equivalents) || []
108
- end
109
-
110
- def _presence_required
111
- self.class.instance_variable_get(:@_presence_required) || []
112
- end
113
-
114
- def _defaults
115
- self.class.instance_variable_get(:@_defaults) || {}
116
- end
117
-
118
- def _required_args
119
- self.class.instance_variable_get(:@_required) || []
61
+ def set_attribute(key, value)
62
+ attrs[key] = value
63
+ define_contextuable_method(key, value)
120
64
  end
121
65
 
122
- def check_input_errors(hash)
123
- unless hash.class <= Hash
124
- fail WrongArgument, "[Contextuable ERROR]: `#{self.class}` expects to receive an `Hash` or and object having `Hash` as ancestor."
125
- end
126
-
127
- _required_args.map(&:to_sym).each do |r|
128
- unless hash.keys.map(&:to_sym).include?(r)
129
- fail RequiredFieldNotPresent, "[Contextuable ERROR]: `#{self.class}` expect to be initialized with `#{r}` as an attribute."
130
- end
131
- end
132
-
133
- _presence_required.map(&:to_sym).each do |r|
134
- if hash[r].nil?
135
- fail PresenceRequired, "[Contextuable ERROR]: `#{self.class}` expects to receive an attribute named `#{r}` not beeing `nil`"
136
- end
137
- end
66
+ def define_contextuable_method(key, value)
67
+ define_singleton_method(key) { attrs.fetch(key) }
68
+ define_singleton_method("#{key}_provided?") { true }
69
+ define_singleton_method("#{key}_not_provided?") { false }
138
70
  end
139
71
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: contextuable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artur Pañach
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-03-20 00:00:00.000000000 Z
11
+ date: 2016-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -71,6 +71,8 @@ files:
71
71
  - bin/setup
72
72
  - contextuable.gemspec
73
73
  - lib/contextuable.rb
74
+ - lib/contextuable/class_methods.rb
75
+ - lib/contextuable/instance_methods.rb
74
76
  homepage: https://www.github.com/arturictus/contextuable
75
77
  licenses:
76
78
  - MIT
@@ -91,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
93
  version: '0'
92
94
  requirements: []
93
95
  rubyforge_project:
94
- rubygems_version: 2.2.3
96
+ rubygems_version: 2.4.6
95
97
  signing_key:
96
98
  specification_version: 4
97
99
  summary: Structs with steroids.