option_initializer 1.1.4 → 1.2.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.
data/README.md CHANGED
@@ -52,6 +52,10 @@ john = Person.new(
52
52
  )
53
53
 
54
54
  # Method call shortcut
55
+ class Person
56
+ option_initializer!
57
+ end
58
+
55
59
  Person.
56
60
  name('John Doe').
57
61
  age(19).
@@ -1,3 +1,3 @@
1
1
  module OptionInitializer
2
- VERSION = "1.1.4"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -1,6 +1,66 @@
1
1
  require "option_initializer/version"
2
2
 
3
3
  module OptionInitializer
4
+ class OptionInitializingTemplate
5
+ attr_reader :options
6
+ alias to_h options
7
+
8
+ const_set :VALIDATORS, []
9
+
10
+ def initialize base, options, need_validation
11
+ validate options if need_validation
12
+ @base = base
13
+ @options = options
14
+ end
15
+
16
+ def new *args, &block
17
+ args = args.dup
18
+ opts = @options
19
+
20
+ # Convention. Deal with it.
21
+ if args.last.is_a?(Hash)
22
+ validate args.last
23
+ opts = opts.merge(args.last)
24
+ args.pop
25
+ else
26
+ opts = opts.dup
27
+ end
28
+
29
+ opts.instance_eval do
30
+ def option_validated?
31
+ true
32
+ end
33
+ end
34
+ args << opts
35
+
36
+ @base.new(*args, &block)
37
+ end
38
+
39
+ def merge opts
40
+ validate opts
41
+ self.class.new @base, @options.merge(opts), false
42
+ end
43
+
44
+ def validate hash
45
+ self.class.const_get(:VALIDATORS).each do |validator|
46
+ hash.each do |k, v|
47
+ validator.call k, v
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ module MethodCallShortcut
54
+ def method_missing sym, *args, &block
55
+ # 1.8
56
+ if @base.instance_methods.map(&:to_sym).include?(sym)
57
+ new.send sym, *args, &block
58
+ else
59
+ raise NoMethodError, "undefined method `#{sym}' for #{self}"
60
+ end
61
+ end
62
+ end
63
+
4
64
  def validate_options options
5
65
  raise TypeError,
6
66
  "wrong argument type #{options.class} (expected Hash)" unless
@@ -16,67 +76,13 @@ module OptionInitializer
16
76
  end
17
77
 
18
78
  def self.included base
19
- base.const_set :OptionInitializing, Class.new {
20
- attr_reader :options
21
- alias to_h options
22
-
23
- const_set :VALIDATORS, []
24
-
25
- def initialize base, options, need_validation
26
- validate options if need_validation
27
- @base = base
28
- @options = options
29
- end
30
-
31
- def new *args, &block
32
- args = args.dup
33
- opts = @options
34
-
35
- # Convention. Deal with it.
36
- if args.last.is_a?(Hash)
37
- validate args.last
38
- opts = opts.merge(args.last)
39
- args.pop
40
- else
41
- opts = opts.dup
42
- end
43
-
44
- opts.instance_eval do
45
- def option_validated?
46
- true
47
- end
48
- end
49
- args << opts
50
-
51
- @base.new(*args, &block)
52
- end
53
-
54
- def merge opts
55
- validate opts
56
- self.class.new @base, @options.merge(opts), false
57
- end
58
-
59
- def validate hash
60
- self.class.const_get(:VALIDATORS).each do |validator|
61
- hash.each do |k, v|
62
- validator.call k, v
63
- end
64
- end
65
- end
66
-
67
- def method_missing sym, *args, &block
68
- # 1.8
69
- if @base.instance_methods.map(&:to_sym).include?(sym)
70
- new.send sym, *args, &block
71
- else
72
- raise NoMethodError, "undefined method `#{sym}' for #{self}"
73
- end
74
- end
75
- } unless base.constants.map(&:to_sym).include?(:OptionInitializing)
79
+ unless base.constants.map(&:to_sym).include?(:OptionInitializing)
80
+ base.const_set :OptionInitializing, OptionInitializingTemplate.dup
81
+ end
76
82
 
77
83
  base.class_eval do
78
84
  class << self
79
- [:option_initializer, :option_validator].each do |m|
85
+ [:option_initializer, :option_initializer!, :option_validator].each do |m|
80
86
  undef_method(m) if method_defined?(m)
81
87
  end
82
88
  end
@@ -133,7 +139,14 @@ module OptionInitializer
133
139
  end
134
140
  end
135
141
  end
142
+
143
+ def base.option_initializer! *syms
144
+ option_initializer(*syms)
145
+ oi = self.const_get(:OptionInitializing)
146
+ oi.class_eval do
147
+ include OptionInitializer::MethodCallShortcut
148
+ end
149
+ end
136
150
  end
137
151
  end
138
152
  end
139
-
@@ -35,7 +35,8 @@ class MyClass2
35
35
  @@validate_count
36
36
  end
37
37
 
38
- option_initializer :aaa, :bbb, :ccc
38
+ option_initializer! :aaa
39
+ option_initializer :bbb, :ccc
39
40
  option_validator do |k, v|
40
41
  @@validate_count += 1
41
42
  case k
@@ -65,10 +66,24 @@ class MyClass2
65
66
  end
66
67
  end
67
68
 
69
+ class MyClass3
70
+ include OptionInitializer
71
+ option_initializer :aaa, :bbb, :ccc
72
+
73
+ def initialize options
74
+ validate_options options
75
+ end
76
+
77
+ def echo a
78
+ yield a
79
+ end
80
+ end
81
+
68
82
  # Excerpt from README
69
83
  class Person
70
84
  include OptionInitializer
71
85
  option_initializer :id, :name, :age, :greetings
86
+ option_initializer!
72
87
 
73
88
  def initialize opts
74
89
  @options = opts
@@ -110,6 +125,10 @@ class TestOptionInitializer < MiniTest::Unit::TestCase
110
125
  def test_method_missing
111
126
  assert_equal 2, MyClass2.aaa(1).bbb(2).num_options(true)
112
127
  assert_equal 2, MyClass2.aaa(1).bbb(2).echo(1) { |a| a * 2 }
128
+
129
+ assert_raises(NoMethodError) do
130
+ MyClass3.aaa(1).bbb(2).echo(1) { |a| a * 2 }
131
+ end
113
132
  end
114
133
 
115
134
  def test_validator
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: option_initializer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.4
4
+ version: 1.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-02 00:00:00.000000000 Z
12
+ date: 2013-03-04 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Object construction with method chaining
15
15
  email: