opt_struct 1.1.0 → 1.2.0

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
  SHA256:
3
- metadata.gz: 33f00177f26d90bc4c9407bfb63860b7ef223f73545311fd26e0e64039f9da92
4
- data.tar.gz: 6d5a5f91b1955e81607abb22c1704b36c3dbb9870a76fa6b26e494e19ccb3b4b
3
+ metadata.gz: 824012017028badde180165fa6280f398cbf138f09f8600319625e92fbaf67ed
4
+ data.tar.gz: 2c612d601c220eb88aaaf656917cd06d0edc7a87b70f84c67cda6b17e6cbbe94
5
5
  SHA512:
6
- metadata.gz: e11a757d9319851bddcc69052076996d618fe2f281822abd281fcfa4cefda3a4d2cda3c424e9ef3882800f76ff7435ddc327f71bfab69742e8ca5dfae98e1003
7
- data.tar.gz: f9174dce367fee3f1fea9bed17c8c004e1b6a8b73d4597e3bcb6bfb02d08d3e36b0b76e3bb0989d66e05983f4d895c6b4e0392a08555edf71887053548972782
6
+ metadata.gz: f7cf9e8c1d9e0b9c40a2f08c1f32784fa61b38a14edac39f4bef3f887845827a57f9b813e2f8df6dbb0436734c8f5895d7b25f45adb2bff3fa82eb7e87766fee
7
+ data.tar.gz: aea1084efba08f15951e7d8629c1a8211d66bddd720dfee19a1c1ec5a8eb52d6c73f047ac4ae8c5b7a969912113b0093249f48f991415ca932170d64e69b956d
data/lib/opt_struct.rb CHANGED
@@ -3,10 +3,11 @@ require "opt_struct/module_methods"
3
3
  require "opt_struct/instance_methods"
4
4
 
5
5
  module OptStruct
6
+ RESERVED_WORDS = %i(class defaults options fetch check_required_args check_required_keys).freeze
6
7
 
7
- def self._inject_struct(target, source, args = [], defaults = {}, &callback)
8
+ def self._inject_struct(target, source, args = [], **defaults, &callback)
8
9
  structs = Array(source.instance_variable_get(:@_opt_structs)).dup
9
- if args.any? || defaults.any? || callback
10
+ if args.any? || defaults.any? || block_given?
10
11
  structs << [args, defaults, callback]
11
12
  end
12
13
  target.instance_variable_set(:@_opt_structs, structs)
@@ -18,7 +19,7 @@ module OptStruct
18
19
  end
19
20
  structs.each do |s_args, s_defaults, s_callback|
20
21
  target.expect_arguments *s_args if s_args.any?
21
- target.options s_defaults if s_defaults.any?
22
+ target.options **s_defaults if s_defaults.any?
22
23
  target.class_exec(&s_callback) if s_callback
23
24
  end
24
25
  else
@@ -38,10 +39,10 @@ module OptStruct
38
39
  end
39
40
 
40
41
  def self.new(*args, **defaults, &callback)
41
- _inject_struct(Class.new, self, args.map(&:to_sym), defaults, &callback)
42
+ _inject_struct(Class.new, self, args.map(&:to_sym), **defaults, &callback)
42
43
  end
43
44
 
44
45
  def self.build(*args, **defaults, &callback)
45
- _inject_struct(Module.new, self, args.map(&:to_sym), defaults, &callback)
46
+ _inject_struct(Module.new, self, args.map(&:to_sym), **defaults, &callback)
46
47
  end
47
48
  end
@@ -1,68 +1,82 @@
1
1
  module OptStruct
2
2
  module ClassMethods
3
3
  def inherited(subclass)
4
- instance_variables.each do |v|
5
- ivar = instance_variable_get(v)
6
- subclass.send(:instance_variable_set, v, ivar.dup) if ivar
4
+ opt_struct_class_constants.each do |c|
5
+ subclass.const_set(c, const_get(c)) if const_defined?(c)
7
6
  end
8
7
  end
9
8
 
9
+ # overwritten if `required` is called
10
10
  def required_keys
11
- @required_keys ||= []
11
+ [].freeze
12
12
  end
13
13
 
14
- def required(*keys)
15
- required_keys.concat keys
16
- option_accessor *keys
14
+ def required(*keys, **options)
15
+ add_required_keys *keys
16
+ option_accessor *keys, **options
17
17
  end
18
18
 
19
- def option_reader(*keys)
19
+ def option_reader(*keys, **options)
20
20
  keys.each do |key|
21
- define_method(key) { options[key] }
21
+ class_eval <<~RUBY
22
+ #{options[:private] ? "private" : ""} def #{key}
23
+ options[:#{key}]
24
+ end
25
+ RUBY
22
26
  end
23
27
  end
24
28
 
25
- def option_writer(*keys)
29
+ def option_writer(*keys, **options)
26
30
  keys.each do |key|
27
- define_method("#{key}=") { |value| options[key] = value }
31
+ class_eval <<~RUBY
32
+ #{options[:private] ? "private" : ""} def #{key}=(value)
33
+ options[:#{key}] = value
34
+ end
35
+ RUBY
28
36
  end
29
37
  end
30
38
 
31
- def option_accessor(*keys)
39
+ def option_accessor(*keys, **options)
32
40
  check_reserved_words(keys)
33
- option_reader *keys
34
- option_writer *keys
41
+ option_reader *keys, **options
42
+ option_writer *keys, **options
35
43
  end
36
44
 
37
- def option(key, default = nil, **options)
45
+ def option(key, default = nil, required: false, **options)
38
46
  default = options[:default] if options.key?(:default)
39
- defaults[key] = default
40
- required_keys << key if options[:required]
41
- option_accessor key
47
+ add_defaults key => default
48
+ add_required_keys key if required
49
+ option_accessor key, **options
42
50
  end
43
51
 
44
52
  def options(*keys, **keys_defaults)
45
53
  option_accessor *keys if keys.any?
46
54
  if keys_defaults.any?
47
- defaults.merge!(keys_defaults)
55
+ add_defaults keys_defaults
48
56
  option_accessor *(keys_defaults.keys - expected_arguments)
49
57
  end
50
58
  end
51
59
 
52
60
  def defaults
53
- @defaults ||= {}
61
+ const_defined?(:OPT_DEFAULTS) ? const_get(:OPT_DEFAULTS) : {}
62
+ end
63
+
64
+ # overwritten if `expect_arguments` is called
65
+ def expected_arguments
66
+ [].freeze
54
67
  end
55
68
 
56
69
  def expect_arguments(*arguments)
57
70
  required(*arguments)
58
- expected_arguments.concat(arguments)
71
+ combined = expected_arguments + arguments
72
+ class_eval <<~EVAL
73
+ def self.expected_arguments
74
+ #{combined.inspect}.freeze
75
+ end
76
+ EVAL
59
77
  end
60
78
  alias_method :expect_argument, :expect_arguments
61
79
 
62
- def expected_arguments
63
- @expected_arguments ||= []
64
- end
65
-
66
80
  def init(meth = nil, &blk)
67
81
  add_callback(:init, meth || blk)
68
82
  end
@@ -76,23 +90,60 @@ module OptStruct
76
90
  add_callback(:around_init, meth || blk)
77
91
  end
78
92
 
79
- def add_callback(name, callback)
80
- @_callbacks ||= {}
81
- @_callbacks[name] ||= []
82
- @_callbacks[name] << callback
93
+ def all_callbacks
94
+ const_defined?(:OPT_CALLBACKS) ? const_get(:OPT_CALLBACKS) : {}.freeze
83
95
  end
84
96
 
85
- def all_callbacks
86
- @_callbacks
97
+ def shareable?
98
+ const_defined?(:SHAREABLE) && const_get(:SHAREABLE)
99
+ end
100
+
101
+ def shareable!
102
+ return if shareable?
103
+ const_set(:SHAREABLE, true)
87
104
  end
88
105
 
89
106
  private
90
107
 
91
- RESERVED_WORDS = %i(class defaults options fetch check_required_args check_required_keys)
108
+ def share(value)
109
+ return value unless shareable?
110
+ defined?(Ractor) ? Ractor.make_shareable(value) : value
111
+ end
112
+
113
+ def add_required_keys(*keys)
114
+ combined = required_keys + keys
115
+ class_eval <<~RUBY
116
+ def self.required_keys
117
+ #{combined.inspect}.freeze
118
+ end
119
+ RUBY
120
+ end
121
+
122
+ def add_defaults(defaults_to_add)
123
+ freezer = defaults.dup
124
+ defaults_to_add.each { |k, v| freezer[k] = share(v) }
125
+ remove_const(:OPT_DEFAULTS) if const_defined?(:OPT_DEFAULTS)
126
+ const_set(:OPT_DEFAULTS, freezer.freeze)
127
+ end
128
+
129
+ def add_callback(name, callback)
130
+ if const_defined?(:OPT_CALLBACKS)
131
+ callbacks_for_name = (all_callbacks[name] || []) + [callback]
132
+ callbacks_hash = all_callbacks.merge(name => callbacks_for_name).freeze
133
+ remove_const(:OPT_CALLBACKS)
134
+ const_set(:OPT_CALLBACKS, callbacks_hash)
135
+ else
136
+ const_set(:OPT_CALLBACKS, { name => [ callback ] })
137
+ end
138
+ end
139
+
140
+ def opt_struct_class_constants
141
+ [:OPT_DEFAULTS, :OPT_CALLBACKS]
142
+ end
92
143
 
93
144
  def check_reserved_words(words)
94
145
  Array(words).each do |word|
95
- if RESERVED_WORDS.member?(word)
146
+ if OptStruct::RESERVED_WORDS.member?(word)
96
147
  raise ArgumentError, "Use of reserved word is not permitted: #{word.inspect}"
97
148
  end
98
149
  end
@@ -22,8 +22,8 @@ module OptStruct
22
22
  options
23
23
  expect_arguments
24
24
  ).each do |class_method|
25
- define_method(class_method) do |*args|
26
- @_opt_structs << [[], {}, -> { send(class_method, *args) }]
25
+ define_method(class_method) do |*args, **options|
26
+ @_opt_structs << [[], {}, -> { send(class_method, *args, **options) }]
27
27
  end
28
28
  end
29
29
  end
@@ -1,3 +1,3 @@
1
1
  module OptStruct
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opt_struct
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carl Zulauf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-09 00:00:00.000000000 Z
11
+ date: 2021-03-30 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Struct with support for keyword params and mixin support
14
14
  email:
@@ -43,7 +43,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
43
43
  - !ruby/object:Gem::Version
44
44
  version: '0'
45
45
  requirements: []
46
- rubygems_version: 3.0.3
46
+ rubygems_version: 3.1.4
47
47
  signing_key:
48
48
  specification_version: 4
49
49
  summary: The Option Struct