subroutine 0.9.0 → 0.10.0.beta

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6ab6d4e06e0400af01060d41f08ba6b61695c24a
4
- data.tar.gz: c6542be4a9832df325fe8f33ad33f297dfd8912c
3
+ metadata.gz: 0dbba6e4428e540eddcfb16df3079f0d9c2db2d2
4
+ data.tar.gz: bd752b132b834c5c35e07fa2434f8d381da3c385
5
5
  SHA512:
6
- metadata.gz: 6331a42ddc585caf91166eb7871e96637712ff09ece5794735c525c044650cf87fb337aa36edb6bb31f084a21d6655df4198932d79b0d5f64b25c5138b34ac28
7
- data.tar.gz: 6d68a2bccecfef89ea3a42689cc565a28b15a4584da2436182fa4ca8cbc25c4e4658e99022b10190622fc57387bfdbd54f028f590a66771a53d9b527f4829d76
6
+ metadata.gz: 439bce703b933575f763ac2aa4428e65babc620275a5ca45cae8ed255592428966867281d20f6093dea7fd2dde8fbc764d82f57dd5bc81e5e21d2562e5f94db0
7
+ data.tar.gz: 8e95b71122f2dcabf504c5c0f7674f12a79923175434cf65300161cc7251123b11a0f9a797889b4bd71b4a2d823921e3d6026f43e9200d8ffbb1d75f17a1a3a9
@@ -1,16 +1,18 @@
1
1
  # frozen_string_literal: true
2
+ require "active_support/concern"
2
3
 
3
4
  module Subroutine
4
5
  module Association
5
- def self.included(base)
6
- base.send :extend, ::Subroutine::Association::ClassMethods
7
- class << base
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ class << self
8
10
  alias_method :field_without_associations, :field
9
11
  alias_method :field, :field_with_associations
10
12
  end
11
13
 
12
- base.send(:alias_method, :setup_fields_without_association, :setup_fields)
13
- base.send(:alias_method, :setup_fields, :setup_fields_with_association)
14
+ alias_method :setup_fields_without_association, :setup_fields
15
+ alias_method :setup_fields, :setup_fields_with_association
14
16
  end
15
17
 
16
18
  module ClassMethods
@@ -75,34 +77,28 @@ module Subroutine
75
77
 
76
78
  integer foreign_key_method
77
79
 
78
- field_without_associations as, options.merge(association: true)
80
+ field_without_associations as, options.merge(association: true, field_writer: false, field_reader: false)
79
81
 
80
82
  class_eval <<-EV, __FILE__, __LINE__ + 1
81
- def #{as}_with_association
83
+ try(:silence_redefinition_of_method, :#{as})
84
+ def #{as}
82
85
  return @#{as} if defined?(@#{as})
83
- @#{as} = begin
84
- #{as}_without_association ||
85
- polymorphic_instance(#{klass.nil? ? foreign_type_method : klass.to_s}, #{foreign_key_method}, #{unscoped.inspect})
86
- end
86
+ @#{as} = polymorphic_instance(#{klass.nil? ? foreign_type_method : klass.to_s}, #{foreign_key_method}, #{unscoped.inspect})
87
87
  end
88
88
 
89
- def #{as}_with_association=(r)
89
+ try(:silence_redefinition_of_method, :#{as}=)
90
+ def #{as}=(r)
90
91
  @#{as} = r
91
- #{poly || klass ? "params['#{foreign_type_method}'] = r.nil? ? nil : #{klass.nil? ? 'r.class.name' : klass.to_s.inspect}" : ''}
92
- params['#{foreign_key_method}'] = r.nil? ? nil : r.id
92
+ #{poly || klass ? "send('#{foreign_type_method}=', r.nil? ? nil : #{klass.nil? ? 'r.class.name' : klass.to_s.inspect})" : ''}
93
+ send('#{foreign_key_method}=', r.nil? ? nil : r.id)
93
94
  r
94
95
  end
95
96
 
97
+ try(:silence_redefinition_of_method, :#{as}_field_provided?)
96
98
  def #{as}_field_provided?
97
99
  field_provided?('#{foreign_key_method}')#{poly ? "&& field_provided?('#{foreign_type_method}')" : ""}
98
100
  end
99
101
  EV
100
-
101
- alias_method :"#{as}_without_association", :"#{as}"
102
- alias_method :"#{as}", :"#{as}_with_association"
103
-
104
- alias_method :"#{as}_without_association=", :"#{as}="
105
- alias_method :"#{as}=", :"#{as}_with_association="
106
102
  end
107
103
  end
108
104
 
@@ -111,6 +107,7 @@ module Subroutine
111
107
 
112
108
  _fields.each_pair do |field, config|
113
109
  next unless config[:association]
110
+ next if config[:mass_assignable] == false
114
111
  next unless @original_params.key?(field)
115
112
 
116
113
  send("#{field}=", @original_params[field]) # this gets the _id and _type into the params hash
@@ -98,10 +98,10 @@ module Subroutine
98
98
  end
99
99
  end
100
100
 
101
- def initialize(*args)
101
+ def initialize(*args, &block)
102
102
  raise Subroutine::Auth::AuthorizationNotDeclaredError unless self.class.authorization_declared
103
103
 
104
- super(args.extract_options!)
104
+ super(args.extract_options!, &block)
105
105
  @skip_auth_checks = false
106
106
  @current_user = args.shift
107
107
 
@@ -72,81 +72,108 @@ module Subroutine
72
72
 
73
73
  protected
74
74
 
75
- def _field(field_name, options = {})
75
+ def _field(field_name, field_writer: true, field_reader: true, **options)
76
76
  self._fields = _fields.merge(field_name.to_sym => options)
77
77
 
78
- class_eval <<-EV, __FILE__, __LINE__ + 1
79
-
80
- def #{field_name}=(v)
81
- config = #{field_name}_config
82
- v = ::Subroutine::TypeCaster.cast(v, config)
83
- @params["#{field_name}"] = v
84
- end
78
+ if field_writer
79
+ class_eval <<-EV, __FILE__, __LINE__ + 1
80
+ try(:silence_redefinition_of_method, :#{field_name}=)
81
+ def #{field_name}=(v)
82
+ config = #{field_name}_config
83
+ @fields_provided["#{field_name}"] = true
84
+ @params["#{field_name}"] = attempt_cast(v, config) do |e|
85
+ "Error during assignment of field `#{field_name}`: \#{e}"
86
+ end
87
+ end
88
+ EV
89
+ end
85
90
 
86
- def #{field_name}
87
- @params.has_key?("#{field_name}") ? @params["#{field_name}"] : @defaults["#{field_name}"]
88
- end
91
+ if field_reader
92
+ class_eval <<-EV, __FILE__, __LINE__ + 1
93
+ try(:silence_redefinition_of_method, :#{field_name})
94
+ def #{field_name}
95
+ @params["#{field_name}"]
96
+ end
97
+ EV
98
+ end
89
99
 
100
+ class_eval <<-EV, __FILE__, __LINE__ + 1
101
+ try(:silence_redefinition_of_method, :#{field_name}_config)
90
102
  def #{field_name}_config
91
103
  _fields[:#{field_name}]
92
104
  end
93
-
94
105
  EV
95
106
  end
96
107
  end
97
108
 
98
109
  def setup_fields(inputs = {})
99
110
  @original_params = inputs.with_indifferent_access
100
- @params = sanitize_params(@original_params)
101
- @defaults = sanitize_defaults
111
+ @defaults = build_defaults
112
+ @fields_provided = {}.with_indifferent_access
113
+ @params = build_params(@original_params, @defaults)
102
114
  end
103
115
 
104
116
  # check if a specific field was provided
105
117
  def field_provided?(key)
106
118
  return send(:"#{key}_field_provided?") if respond_to?(:"#{key}_field_provided?", true)
107
119
 
108
- @params.key?(key)
120
+ !!@fields_provided[key]
109
121
  end
110
122
 
111
123
  # if you want to use strong parameters or something in your form object you can do so here.
112
124
  # by default we just slice the inputs to the defined fields
113
- def sanitize_params(inputs)
125
+ def build_params(inputs, defaults)
114
126
  out = {}.with_indifferent_access
127
+
115
128
  _fields.each_pair do |field, config|
116
- next unless inputs.key?(field)
117
129
 
118
- begin
119
- out[field] = ::Subroutine::TypeCaster.cast(inputs[field], config)
120
- rescue ::Subroutine::TypeCaster::TypeCastError => e
121
- raise ::Subroutine::TypeCaster::TypeCastError, "Error for field `#{field}`: #{e}"
130
+ if config[:mass_assignable] == false && inputs.key?(field)
131
+ raise ArgumentError, "`#{field}` is not mass assignable"
132
+ end
133
+
134
+ if inputs.key?(field)
135
+ @fields_provided[field] = true
136
+ out[field] = attempt_cast(inputs[field], config) do |e|
137
+ "Error for field `#{field}`: #{e}"
138
+ end
139
+ elsif defaults.key?(field)
140
+ out[field] = defaults[field]
141
+ else
142
+ next
122
143
  end
123
144
  end
124
145
 
125
146
  out
126
147
  end
127
148
 
128
- def params_with_defaults
129
- @defaults.merge(@params)
130
- end
131
-
132
- def sanitize_defaults
133
- defaults = {}.with_indifferent_access
149
+ def build_defaults
150
+ @defaults = {}.with_indifferent_access
134
151
 
135
152
  _fields.each_pair do |field, config|
136
- next if config[:default].nil?
153
+ next unless config.key?(:default)
137
154
 
138
155
  deflt = config[:default]
139
156
  if deflt.respond_to?(:call)
140
157
  deflt = deflt.call
141
- elsif deflt.duplicable? # from active_support
158
+ elsif deflt.try(:duplicable?) # from active_support
142
159
  # Some classes of default values need to be duplicated, or the instance field value will end up referencing
143
160
  # the class global default value, and potentially modify it.
144
161
  deflt = deflt.deep_dup # from active_support
145
162
  end
146
- defaults[field] = ::Subroutine::TypeCaster.cast(deflt, config)
163
+
164
+ @defaults[field.to_s] = attempt_cast(deflt, config) do |e|
165
+ "Error for default `#{field}`: #{e}"
166
+ end
147
167
  end
148
168
 
149
- defaults
169
+ @defaults
170
+ end
171
+
172
+ def attempt_cast(value, config)
173
+ ::Subroutine::TypeCaster.cast(value, config)
174
+ rescue ::Subroutine::TypeCaster::TypeCastError => e
175
+ message = block_given? ? yield(e) : e.to_s
176
+ raise ::Subroutine::TypeCaster::TypeCastError, message, e.backtrace
150
177
  end
151
178
 
152
179
  end
data/lib/subroutine/op.rb CHANGED
@@ -4,16 +4,15 @@ require "active_model"
4
4
 
5
5
  require "subroutine/fields"
6
6
  require "subroutine/failure"
7
- require "subroutine/filtered_errors"
8
7
  require "subroutine/output_not_set_error"
9
8
  require "subroutine/unknown_output_error"
10
9
 
11
10
  module Subroutine
12
11
  class Op
13
12
 
14
- include ::Subroutine::Fields
15
- include ::ActiveModel::Model
13
+ include ::ActiveModel::Validations
16
14
  include ::ActiveModel::Validations::Callbacks
15
+ include ::Subroutine::Fields
17
16
 
18
17
  DEFAULT_OUTPUT_OPTIONS = {
19
18
  required: true,
@@ -34,14 +33,8 @@ module Subroutine
34
33
  end
35
34
  end
36
35
 
37
- def ignore_error(*field_names)
38
- field_names.each do |f|
39
- _ignore_errors(f)
40
- end
41
- end
42
- alias ignore_errors ignore_error
43
-
44
36
  def submit!(*args)
37
+ raise ArgumentError, "Blocks cannot be provided to `submit!`" if block_given?
45
38
  op = new(*args)
46
39
  op.submit!
47
40
 
@@ -49,6 +42,7 @@ module Subroutine
49
42
  end
50
43
 
51
44
  def submit(*args)
45
+ raise ArgumentError, "Blocks cannot be provided to `submit`." if block_given?
52
46
  op = new(*args)
53
47
  op.submit
54
48
  op
@@ -65,15 +59,9 @@ module Subroutine
65
59
  end
66
60
  end
67
61
 
68
- _ignore_errors(field_name) if options[:ignore_errors]
69
-
70
62
  result
71
63
  end
72
64
 
73
- def _ignore_errors(field_name)
74
- self._error_ignores = _error_ignores.merge(field_name.to_sym => true)
75
- end
76
-
77
65
  end
78
66
 
79
67
  class_attribute :_outputs
@@ -82,16 +70,10 @@ module Subroutine
82
70
  class_attribute :_error_map
83
71
  self._error_map = {}
84
72
 
85
- class_attribute :_error_ignores
86
- self._error_ignores = {}
87
-
88
73
  def initialize(inputs = {})
89
74
  setup_fields(inputs)
90
75
  @outputs = {}
91
- end
92
-
93
- def errors
94
- @filtered_errors ||= Subroutine::FilteredErrors.new(super)
76
+ yield self if block_given?
95
77
  end
96
78
 
97
79
  def output(name, value)
@@ -175,8 +157,6 @@ module Subroutine
175
157
  error_object = error_object.errors if error_object.respond_to?(:errors)
176
158
 
177
159
  error_object.each do |k, v|
178
- next if _error_ignores[k.to_sym]
179
-
180
160
  if respond_to?(k)
181
161
  errors.add(k, v)
182
162
  elsif _error_map[k.to_sym]
@@ -2,9 +2,9 @@
2
2
 
3
3
  module Subroutine
4
4
  MAJOR = 0
5
- MINOR = 9
5
+ MINOR = 10
6
6
  PATCH = 0
7
- PRE = nil
7
+ PRE = "beta"
8
8
 
9
9
  VERSION = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
10
10
  end
data/subroutine.gemspec CHANGED
@@ -26,4 +26,5 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "minitest"
27
27
  spec.add_development_dependency "minitest-reporters"
28
28
  spec.add_development_dependency "mocha"
29
+ spec.add_development_dependency "byebug"
29
30
  end
@@ -151,33 +151,16 @@ module Subroutine
151
151
  assert_equal 'foo@bar.com', op.created_user.email_address
152
152
  end
153
153
 
154
- def test_it_ignores_specific_errors
155
- op = ::WhateverSignupOp.submit
156
- assert_equal [], op.errors[:whatever]
157
- end
158
-
159
- def test_it_does_not_inherit_ignored_errors
160
- op = ::WhateverSignupOp.new
161
- other = ::SignupOp.new
162
- other.errors.add(:whatever, 'fail')
163
- op.send(:inherit_errors, other)
164
- assert_equal [], op.errors[:whatever]
165
- end
166
-
167
154
  def test_it_sets_the_params_and_defaults_immediately
168
155
  op = ::AdminSignupOp.new(email: 'foo')
169
156
  assert_equal({
170
- 'email' => 'foo'
157
+ 'email' => 'foo',
158
+ 'privileges' => 'min',
171
159
  }, op.params)
172
160
 
173
161
  assert_equal({
174
162
  'privileges' => 'min'
175
163
  }, op.defaults)
176
-
177
- assert_equal({
178
- 'email' => 'foo',
179
- 'privileges' => 'min'
180
- }, op.params_with_defaults)
181
164
  end
182
165
 
183
166
  def test_it_allows_defaults_to_be_overridden
@@ -188,14 +171,7 @@ module Subroutine
188
171
  'privileges' => nil
189
172
  }, op.params)
190
173
 
191
- assert_equal({
192
- 'privileges' => 'min'
193
- }, op.defaults)
194
-
195
- assert_equal({
196
- 'email' => 'foo',
197
- 'privileges' => nil
198
- }, op.params_with_defaults)
174
+ assert_equal({"privileges" => "min"}, op.defaults)
199
175
  end
200
176
 
201
177
  def test_it_overriding_default_does_not_alter_default
@@ -212,11 +188,6 @@ module Subroutine
212
188
  assert_equal({
213
189
  'privileges' => 'min'
214
190
  }, op.defaults)
215
-
216
- assert_equal({
217
- 'email' => 'foo',
218
- 'privileges' => nil
219
- }, op.params_with_defaults)
220
191
  end
221
192
 
222
193
  def test_it_overrides_defaults_with_nils
@@ -229,10 +200,10 @@ module Subroutine
229
200
 
230
201
  def test_it_casts_params_on_the_way_in
231
202
  op = ::TypeCastOp.new(integer_input: '25')
232
- assert_equal(25, op.params_with_defaults['integer_input'])
203
+ assert_equal(25, op.params['integer_input'])
233
204
 
234
205
  op.decimal_input = '25.3'
235
- assert_equal(BigDecimal('25.3'), op.params_with_defaults['decimal_input'])
206
+ assert_equal(BigDecimal('25.3'), op.params['decimal_input'])
236
207
  end
237
208
 
238
209
  def test_it_allow_retrival_of_outputs
@@ -278,5 +249,34 @@ module Subroutine
278
249
  refute_nil found, 'Expected backtrace to include original caller of foo'
279
250
  end
280
251
  end
252
+
253
+ def test_a_block_is_accepted_on_instantiation
254
+ op = ::SignupOp.new do |o|
255
+ o.email = "foo@bar.com"
256
+ o.password = "password123!"
257
+ end
258
+
259
+ assert_equal "foo@bar.com", op.email
260
+ assert_equal "password123!", op.password
261
+
262
+ assert_equal true, op.field_provided?(:email)
263
+ assert_equal true, op.field_provided?(:password)
264
+ end
265
+
266
+ def test_a_block_is_not_accepted_with_submit
267
+ assert_raises ::ArgumentError do
268
+ ::SignupOp.submit! do |o|
269
+ o.email = "foo@bar.com"
270
+ o.password = "password123!"
271
+ end
272
+ end
273
+
274
+ assert_raises ::ArgumentError do
275
+ ::SignupOp.submit do |o|
276
+ o.email = "foo@bar.com"
277
+ o.password = "password123!"
278
+ end
279
+ end
280
+ end
281
281
  end
282
282
  end
@@ -14,6 +14,8 @@ module Subroutine
14
14
  integer :bar, default: -> { 3 }
15
15
  date :baz
16
16
 
17
+ string :protekted, mass_assignable: false
18
+
17
19
  def initialize(options = {})
18
20
  setup_fields(options)
19
21
  end
@@ -21,10 +23,11 @@ module Subroutine
21
23
  end
22
24
 
23
25
  def test_fields_are_configured
24
- assert_equal 3, Whatever._fields.size
26
+ assert_equal 4, Whatever._fields.size
25
27
  assert_equal :string, Whatever._fields[:foo][:type]
26
28
  assert_equal :integer, Whatever._fields[:bar][:type]
27
29
  assert_equal :date, Whatever._fields[:baz][:type]
30
+ assert_equal :string, Whatever._fields[:protekted][:type]
28
31
  end
29
32
 
30
33
  def test_field_defaults_are_handled
@@ -43,13 +46,6 @@ module Subroutine
43
46
  instance = Whatever.new(foo: "abc")
44
47
  assert_equal true, instance.field_provided?(:foo)
45
48
  assert_equal false, instance.field_provided?(:bar)
46
- end
47
-
48
- def test_field_provided
49
-
50
- instance = Whatever.new(foo: "abc")
51
- assert_equal true, instance.field_provided?(:foo)
52
- assert_equal false, instance.field_provided?(:bar)
53
49
 
54
50
  instance = DefaultsOp.new
55
51
  assert_equal false, instance.field_provided?(:foo)
@@ -58,18 +54,39 @@ module Subroutine
58
54
  assert_equal true, instance.field_provided?(:foo)
59
55
  end
60
56
 
57
+ def test_field_provided_include_manual_assigned_fields
58
+ instance = Whatever.new
59
+ instance.foo = "bar"
60
+
61
+ assert_equal true, instance.field_provided?(:foo)
62
+ assert_equal false, instance.field_provided?(:bar)
63
+ end
64
+
61
65
  def test_invalid_typecast
62
66
  assert_raises "Error for field `baz`: invalid date" do
63
67
  Whatever.new(baz: "2015-13-01")
64
68
  end
65
69
  end
66
70
 
67
- def test_params
71
+ def test_params_include_defaults
68
72
  instance = Whatever.new(foo: "abc")
69
- assert_equal({ "foo" => "abc" }, instance.params)
70
- assert_equal({ "foo" => "abc", "bar" => 3 }, instance.params_with_defaults)
73
+ assert_equal({ "foo" => "abc", "bar" => 3 }, instance.params)
71
74
  assert_equal({ "foo" => "foo", "bar" => 3 }, instance.defaults)
72
75
  end
73
76
 
77
+ def test_fields_can_opt_out_of_mass_assignment
78
+ assert_raises "`protekted` is not mass assignable" do
79
+ Whatever.new(foo: "abc", protekted: "foo")
80
+ end
81
+ end
82
+
83
+ def test_non_mass_assignment_fields_can_be_individually_assigned
84
+ instance = Whatever.new(foo: "abc")
85
+ instance.protekted = "bar"
86
+
87
+ assert_equal "bar", instance.protekted
88
+ assert_equal true, instance.field_provided?(:protekted)
89
+ end
90
+
74
91
  end
75
92
  end
data/test/support/ops.rb CHANGED
@@ -64,10 +64,6 @@ class SignupOp < ::Subroutine::Op
64
64
  ::User
65
65
  end
66
66
  end
67
- class WhateverSignupOp < ::SignupOp
68
- string :whatever, ignore_errors: true
69
- validates :whatever, presence: true
70
- end
71
67
 
72
68
  class AdminSignupOp < ::SignupOp
73
69
  field :privileges, default: 'min'
data/test/test_helper.rb CHANGED
@@ -7,6 +7,8 @@ require 'minitest/unit'
7
7
  require 'minitest/reporters'
8
8
  require 'mocha/minitest'
9
9
 
10
+ require "byebug"
11
+
10
12
  Minitest::Reporters.use!([Minitest::Reporters::DefaultReporter.new])
11
13
 
12
14
  class TestCase < ::Minitest::Test; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: subroutine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Nelson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-24 00:00:00.000000000 Z
11
+ date: 2019-11-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: byebug
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description: An interface for creating feature-driven operations.
112
126
  email:
113
127
  - mike@mnelson.io
@@ -134,7 +148,6 @@ files:
134
148
  - lib/subroutine/auth.rb
135
149
  - lib/subroutine/failure.rb
136
150
  - lib/subroutine/fields.rb
137
- - lib/subroutine/filtered_errors.rb
138
151
  - lib/subroutine/op.rb
139
152
  - lib/subroutine/output_not_set_error.rb
140
153
  - lib/subroutine/type_caster.rb
@@ -163,9 +176,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
163
176
  version: '0'
164
177
  required_rubygems_version: !ruby/object:Gem::Requirement
165
178
  requirements:
166
- - - ">="
179
+ - - ">"
167
180
  - !ruby/object:Gem::Version
168
- version: '0'
181
+ version: 1.3.1
169
182
  requirements: []
170
183
  rubyforge_project:
171
184
  rubygems_version: 2.6.14.4
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Subroutine
4
- class FilteredErrors < SimpleDelegator
5
- def add(*args)
6
- return if __getobj__.instance_variable_get('@base')._error_ignores[args[0].to_sym]
7
-
8
- __getobj__.add(*args)
9
- end
10
- end
11
- end