classx 0.0.2 → 0.0.3
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/ChangeLog +84 -0
- data/README +4 -2
- data/Rakefile +1 -1
- data/bench/attribute_set.rb +56 -0
- data/bench/initialize.rb +59 -0
- data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-block_rb.html +1 -1
- data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-callbacks_rb.html +1 -1
- data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-change_rb.html +1 -1
- data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-hunk_rb.html +1 -1
- data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs_rb.html +1 -1
- data/doc/output/coverage/-Library-Ruby-Gems-gems-rcov-0_8_1_2_0-lib-rcov_rb.html +1 -1
- data/doc/output/coverage/index.html +27 -27
- data/doc/output/coverage/lib-classx-attribute_rb.html +82 -75
- data/doc/output/coverage/lib-classx-attributes_rb.html +101 -94
- data/doc/output/coverage/lib-classx-validate_rb.html +14 -11
- data/doc/output/coverage/lib-classx_rb.html +75 -65
- data/example/commandable.rb +9 -3
- data/lib/classx.rb +12 -2
- data/lib/classx/attribute.rb +10 -3
- data/lib/classx/attributes.rb +10 -3
- data/lib/classx/commandable.rb +27 -7
- data/lib/classx/declare.rb +12 -0
- data/lib/classx/role/logger.rb +70 -0
- data/lib/classx/validate.rb +6 -3
- data/spec/classx/default_option_spec.rb +16 -12
- data/spec/classx/handles_spec.rb +5 -2
- data/spec/classx/with_coerce.rb +12 -4
- data/spec/classx/with_extend.rb +3 -1
- data/spec/classx/with_include.rb +3 -1
- data/spec/classx/with_multiple_class_spec.rb +4 -2
- data/spec/classx/without_accessor_spec.rb +2 -1
- data/spec/classx/without_anyoption_spec.rb +3 -1
- data/spec/classx/writable_option_spec.rb +8 -4
- data/spec/classx_attributes_spec.rb +6 -1
- data/tasks/basic_config.rake +1 -1
- metadata +7 -2
data/lib/classx.rb
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
require 'classx/attribute'
|
2
2
|
require 'classx/attributes'
|
3
3
|
|
4
|
-
|
4
|
+
module ClassX
|
5
|
+
autoload :Validate, 'classx/validate'
|
6
|
+
autoload :Commandable, 'classx/commandable'
|
7
|
+
autoload :Declare, 'classx/declare'
|
8
|
+
autoload :Util, 'classx/util'
|
9
|
+
module Role
|
10
|
+
autoload :Logger, 'classx/role/logger'
|
11
|
+
end
|
12
|
+
|
5
13
|
class InstanceException < Exception; end
|
6
14
|
class AttrRequiredError < InstanceException; end
|
7
15
|
class InvalidAttrArgument < InstanceException; end
|
@@ -9,7 +17,9 @@ class ClassX
|
|
9
17
|
class OptionalAttrShouldBeWritable < Exception; end
|
10
18
|
class RequiredAttrShouldNotHaveDefault < Exception; end
|
11
19
|
|
12
|
-
|
20
|
+
def self.included klass
|
21
|
+
klass.extend(Attributes)
|
22
|
+
end
|
13
23
|
|
14
24
|
def initialize *args
|
15
25
|
hash = before_init(*args)
|
data/lib/classx/attribute.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
module ClassX
|
2
2
|
class AttributeFactory
|
3
3
|
def self.create args
|
4
4
|
klass = Class.new
|
@@ -109,7 +109,11 @@ class ClassX
|
|
109
109
|
when Proc
|
110
110
|
args[:default].call(parent)
|
111
111
|
else
|
112
|
-
|
112
|
+
begin
|
113
|
+
args[:default].dup
|
114
|
+
rescue Exception
|
115
|
+
args[:default]
|
116
|
+
end
|
113
117
|
end
|
114
118
|
end
|
115
119
|
|
@@ -123,6 +127,9 @@ class ClassX
|
|
123
127
|
return args[:lazy]
|
124
128
|
end
|
125
129
|
|
130
|
+
define_method :inspect do
|
131
|
+
"ClassX::Attribute[#{self.config.inspect}]"
|
132
|
+
end
|
126
133
|
end
|
127
134
|
__send__ :extend, tmp_mod
|
128
135
|
|
@@ -168,7 +175,7 @@ class ClassX
|
|
168
175
|
end
|
169
176
|
|
170
177
|
define_method :inspect do
|
171
|
-
"<#ClassX::Attribute
|
178
|
+
"<#ClassX::Attribute:#{object_id} #{ @data.nil? ? '@data=nil' : '@data=' + @data.inspect } config=#{self.class.config.inspect}>"
|
172
179
|
end
|
173
180
|
end
|
174
181
|
|
data/lib/classx/attributes.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
module ClassX
|
2
2
|
module Attributes
|
3
3
|
ATTRIBUTE_REGEX = /\Aattribute_of:(\w+)\z/
|
4
4
|
|
@@ -18,6 +18,12 @@ class ClassX
|
|
18
18
|
def define_attribute name, attribute
|
19
19
|
klass_attribute = ClassX::AttributeFactory.create(attribute)
|
20
20
|
mod = Module.new
|
21
|
+
begin
|
22
|
+
mod = self.const_get('ClassMethods')
|
23
|
+
rescue NameError => e
|
24
|
+
mod = Module.new
|
25
|
+
const_set('ClassMethods', mod)
|
26
|
+
end
|
21
27
|
mod.module_eval do
|
22
28
|
define_method "attribute_of:#{name}" do
|
23
29
|
klass_attribute
|
@@ -26,7 +32,7 @@ class ClassX
|
|
26
32
|
private "attribute_of:#{name}"
|
27
33
|
end
|
28
34
|
self.extend(mod)
|
29
|
-
@__attribute_of ||=
|
35
|
+
@__attribute_of ||= self.attribute_of
|
30
36
|
@__attribute_of[name] = klass_attribute
|
31
37
|
|
32
38
|
define_method "attribute_of:#{name}" do
|
@@ -77,8 +83,9 @@ class ClassX
|
|
77
83
|
|
78
84
|
alias has add_attribute
|
79
85
|
|
86
|
+
# hook for module to ClassX base class.
|
80
87
|
def included klass
|
81
|
-
klass.extend
|
88
|
+
klass.extend(self.const_get('ClassMethods'))
|
82
89
|
end
|
83
90
|
|
84
91
|
end
|
data/lib/classx/commandable.rb
CHANGED
@@ -2,7 +2,7 @@ require 'optparse'
|
|
2
2
|
|
3
3
|
$ClassXCommandableMappingOf = {}
|
4
4
|
|
5
|
-
|
5
|
+
module ClassX
|
6
6
|
module Commandable
|
7
7
|
class MissingCoerceMapping < Exception; end
|
8
8
|
|
@@ -11,25 +11,45 @@ class ClassX
|
|
11
11
|
begin
|
12
12
|
opt.banner = "#{$0} [options]"
|
13
13
|
value_of = {}
|
14
|
-
|
14
|
+
short_option_of = {}
|
15
|
+
attribute_of.keys.sort.each do |key|
|
16
|
+
val = attribute_of[key]
|
17
|
+
next if val.config[:no_cmd_option]
|
15
18
|
|
16
|
-
val_format = val.value_class ? val.value_class : "VAL"
|
19
|
+
val_format = val.value_class ? "#{val.value_class}" : "VAL"
|
17
20
|
if val.optional?
|
18
|
-
val_format = "[
|
21
|
+
val_format = "[#{val_format}]"
|
22
|
+
end
|
23
|
+
|
24
|
+
short_option = key.split(//).first
|
25
|
+
unless short_option_of[short_option]
|
26
|
+
short_option_of[short_option] = key
|
19
27
|
end
|
20
28
|
|
21
29
|
if val.value_class
|
22
30
|
begin
|
23
|
-
|
31
|
+
if short_option_of[short_option] == key
|
32
|
+
opt.on("-#{short_option}", "--#{key} #{val_format}", val.value_class, val.desc) {|v| value_of[key] = v }
|
33
|
+
else
|
34
|
+
opt.on("--#{key} #{val_format}", val.value_class, val.desc) {|v| value_of[key] = v }
|
35
|
+
end
|
24
36
|
rescue Exception => e
|
25
37
|
if $ClassXCommandableMappingOf[val.value_class]
|
26
|
-
|
38
|
+
if short_option_of[short_option] == key
|
39
|
+
opt.on("-#{short_option}", "--#{key} #{$ClassXCommandableMappingOf[val.value_class]}", $ClassXCommandableMappingOf[val.value_class], val.desc) {|v| value_of[key] = v }
|
40
|
+
else
|
41
|
+
opt.on("--#{key} #{$ClassXCommandableMappingOf[val.value_class]}", $ClassXCommandableMappingOf[val.value_class], val.desc) {|v| value_of[key] = v }
|
42
|
+
end
|
27
43
|
else
|
28
44
|
raise MissingCoerceMapping, "missing coerce rule. please specify $ClassXCommandableMappingOf"
|
29
45
|
end
|
30
46
|
end
|
31
47
|
else
|
32
|
-
|
48
|
+
if short_option_of[short_option] == key
|
49
|
+
opt.on("-#{short_option}", "--#{key} #{val_format}") {|v| value_of[key] = v }
|
50
|
+
else
|
51
|
+
opt.on("--#{key} #{val_format}") {|v| value_of[key] = v }
|
52
|
+
end
|
33
53
|
end
|
34
54
|
end
|
35
55
|
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module ClassX
|
4
|
+
module Role
|
5
|
+
# SYNOPSIS
|
6
|
+
#
|
7
|
+
# require 'classx/role/logger'
|
8
|
+
# class YourApp < ClassX
|
9
|
+
# extends ClassX::Commandable
|
10
|
+
# include ClassX::Role::Logger
|
11
|
+
#
|
12
|
+
# def run
|
13
|
+
# logger.debug("debug!!")
|
14
|
+
# # do something
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# and run following:
|
19
|
+
#
|
20
|
+
# $ your_app.rb --logfile log/debug.log --log_level debug
|
21
|
+
#
|
22
|
+
# SEE ALSO: +ClassX::Commandable+
|
23
|
+
#
|
24
|
+
module Logger
|
25
|
+
extend ClassX::Attributes
|
26
|
+
|
27
|
+
module ToLogLevel
|
28
|
+
def to_log_level str=self.get
|
29
|
+
::Logger::Severity.const_get(str.upcase)
|
30
|
+
end
|
31
|
+
|
32
|
+
alias to_i to_log_level
|
33
|
+
end
|
34
|
+
|
35
|
+
has :logger,
|
36
|
+
:lazy => true,
|
37
|
+
:optional => true,
|
38
|
+
:no_cmd_option => true,
|
39
|
+
:default => proc {|mine|
|
40
|
+
logger = ::Logger.new(mine.logfile)
|
41
|
+
logger.level = mine.attribute_of['log_level'].to_i
|
42
|
+
logger.progname = $0
|
43
|
+
|
44
|
+
logger
|
45
|
+
}
|
46
|
+
|
47
|
+
has :log_level,
|
48
|
+
:kind_of => String,
|
49
|
+
:desc => 'log_level (debug|info|warn|error|fatal) (default info)',
|
50
|
+
:optional => true,
|
51
|
+
:default => 'info',
|
52
|
+
:include => ToLogLevel,
|
53
|
+
:validate => proc {|val|
|
54
|
+
begin
|
55
|
+
::Logger::Severity.const_get(val.upcase)
|
56
|
+
rescue NameError => e
|
57
|
+
return false
|
58
|
+
end
|
59
|
+
true
|
60
|
+
}
|
61
|
+
|
62
|
+
has :logfile,
|
63
|
+
:kind_of => String,
|
64
|
+
:desc => 'output logfile. (default STDERR)',
|
65
|
+
:optional => true,
|
66
|
+
:default => $stderr # hmm, is name bad?
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/classx/validate.rb
CHANGED
@@ -5,8 +5,8 @@ module ClassX::Validate
|
|
5
5
|
#
|
6
6
|
# require 'classx/validate'
|
7
7
|
#
|
8
|
-
# class YourClass
|
9
|
-
# include Validate
|
8
|
+
# class YourClass
|
9
|
+
# include ClassX::Validate
|
10
10
|
#
|
11
11
|
# def run params
|
12
12
|
# validate params do
|
@@ -27,7 +27,10 @@ module ClassX::Validate
|
|
27
27
|
@@__validate_cached ||= {}
|
28
28
|
uniq_key = caller[0]
|
29
29
|
unless @@__validate_cached[uniq_key]
|
30
|
-
@@__validate_cached[uniq_key] = Class.new
|
30
|
+
@@__validate_cached[uniq_key] = Class.new
|
31
|
+
@@__validate_cached[uniq_key].class_eval do
|
32
|
+
include ::ClassX
|
33
|
+
end
|
31
34
|
@@__validate_cached[uniq_key].class_eval(&block)
|
32
35
|
end
|
33
36
|
@@__validate_cached[uniq_key].new hash
|
@@ -6,8 +6,9 @@ describe ClassX do
|
|
6
6
|
describe 'with :default option' do
|
7
7
|
describe 'when value is Proc' do
|
8
8
|
before do
|
9
|
-
@class = Class.new
|
9
|
+
@class = Class.new
|
10
10
|
@class.class_eval do
|
11
|
+
include ClassX
|
11
12
|
has :x, :default => proc { Object.new }
|
12
13
|
end
|
13
14
|
end
|
@@ -34,8 +35,9 @@ describe ClassX do
|
|
34
35
|
|
35
36
|
describe 'when value is not Proc' do
|
36
37
|
before do
|
37
|
-
@class = Class.new
|
38
|
+
@class = Class.new
|
38
39
|
@class.class_eval do
|
40
|
+
include ClassX
|
39
41
|
has :x, :default => []
|
40
42
|
end
|
41
43
|
end
|
@@ -43,17 +45,14 @@ describe ClassX do
|
|
43
45
|
it 'should have any value when instanciate' do
|
44
46
|
@class.new.x.should == []
|
45
47
|
end
|
46
|
-
|
47
|
-
it 'should have the same object_id between some instance' do
|
48
|
-
@class.new.x.should equal(@class.new.x)
|
49
|
-
end
|
50
48
|
end
|
51
49
|
end
|
52
50
|
|
53
51
|
describe 'with :optional is false' do
|
54
52
|
before do
|
55
|
-
@class = Class.new
|
53
|
+
@class = Class.new
|
56
54
|
@class.class_eval do
|
55
|
+
include ClassX
|
57
56
|
has :x, :optional => false
|
58
57
|
end
|
59
58
|
end
|
@@ -74,8 +73,9 @@ describe ClassX do
|
|
74
73
|
describe ':optional is false and with :default option' do
|
75
74
|
it 'should raise ClassX::RequiredAttrShouldNotHaveDefault' do
|
76
75
|
lambda {
|
77
|
-
klass = Class.new
|
76
|
+
klass = Class.new
|
78
77
|
klass.class_eval do
|
78
|
+
include ClassX
|
79
79
|
has :x, :optional => false, :default => 1
|
80
80
|
end
|
81
81
|
}.should raise_error(ClassX::RequiredAttrShouldNotHaveDefault)
|
@@ -84,8 +84,9 @@ describe ClassX do
|
|
84
84
|
|
85
85
|
describe 'declare attribute without :optional and :default option' do
|
86
86
|
before do
|
87
|
-
@class = Class.new
|
87
|
+
@class = Class.new
|
88
88
|
@class.class_eval do
|
89
|
+
include ClassX
|
89
90
|
has :x, :kind_of => Integer
|
90
91
|
end
|
91
92
|
end
|
@@ -97,8 +98,9 @@ describe ClassX do
|
|
97
98
|
|
98
99
|
describe ':optional is true and without :default option' do
|
99
100
|
before do
|
100
|
-
@class = Class.new
|
101
|
+
@class = Class.new
|
101
102
|
@class.class_eval do
|
103
|
+
include ClassX
|
102
104
|
has :x, :optional => true, :kind_of => Integer
|
103
105
|
end
|
104
106
|
end
|
@@ -111,8 +113,9 @@ describe ClassX do
|
|
111
113
|
describe 'with :optional is true' do
|
112
114
|
describe 'without :writable option' do
|
113
115
|
before do
|
114
|
-
@class = Class.new
|
116
|
+
@class = Class.new
|
115
117
|
@class.class_eval do
|
118
|
+
include ClassX
|
116
119
|
has :x, :optional => true
|
117
120
|
end
|
118
121
|
end
|
@@ -124,8 +127,9 @@ describe ClassX do
|
|
124
127
|
|
125
128
|
describe 'not attribute param exist in #initialize argument' do
|
126
129
|
before do
|
127
|
-
@class = Class.new
|
130
|
+
@class = Class.new
|
128
131
|
@class.class_eval do
|
132
|
+
include ClassX
|
129
133
|
has :x
|
130
134
|
end
|
131
135
|
end
|
data/spec/classx/handles_spec.rb
CHANGED
@@ -5,8 +5,9 @@ describe ClassX do
|
|
5
5
|
describe '#has' do
|
6
6
|
describe 'with handles option as Hash' do
|
7
7
|
before do
|
8
|
-
@class1 = Class.new
|
8
|
+
@class1 = Class.new
|
9
9
|
@class1.class_eval do
|
10
|
+
include ClassX
|
10
11
|
has :x, :handles => { :x_inspect => :inspect }
|
11
12
|
end
|
12
13
|
end
|
@@ -24,8 +25,10 @@ describe ClassX do
|
|
24
25
|
|
25
26
|
describe 'with handles option as Array' do
|
26
27
|
before do
|
27
|
-
@class1 = Class.new
|
28
|
+
@class1 = Class.new
|
28
29
|
@class1.class_eval do
|
30
|
+
include ClassX
|
31
|
+
|
29
32
|
has :x, :handles => [ :length ]
|
30
33
|
end
|
31
34
|
end
|
data/spec/classx/with_coerce.rb
CHANGED
@@ -6,8 +6,10 @@ describe ClassX do
|
|
6
6
|
describe 'with coece' do
|
7
7
|
describe 'when Array is value' do
|
8
8
|
before do
|
9
|
-
@class = Class.new
|
9
|
+
@class = Class.new
|
10
10
|
@class.class_eval do
|
11
|
+
include ClassX
|
12
|
+
|
11
13
|
has :x, :isa => Integer, :coerce => [
|
12
14
|
{ proc {|val| val.respond_to? :to_i } => proc {|val| val.to_i } },
|
13
15
|
{ proc {|val| val.respond_to? :to_s } => proc {|val| val.to_s } },
|
@@ -26,8 +28,10 @@ describe ClassX do
|
|
26
28
|
|
27
29
|
describe 'when Proc is key' do
|
28
30
|
before do
|
29
|
-
@class = Class.new
|
31
|
+
@class = Class.new
|
30
32
|
@class.class_eval do
|
33
|
+
include ClassX
|
34
|
+
|
31
35
|
has :x, :isa => Integer, :coerce => { proc {|val| val.respond_to? :to_i } => proc {|val| val.to_i } }
|
32
36
|
end
|
33
37
|
end
|
@@ -43,8 +47,10 @@ describe ClassX do
|
|
43
47
|
|
44
48
|
describe 'when Symbol is key' do
|
45
49
|
before do
|
46
|
-
@class = Class.new
|
50
|
+
@class = Class.new
|
47
51
|
@class.class_eval do
|
52
|
+
include ClassX
|
53
|
+
|
48
54
|
has :x, :isa => Integer, :coerce => { :to_i => proc {|val| val.to_i } }
|
49
55
|
end
|
50
56
|
end
|
@@ -60,8 +66,10 @@ describe ClassX do
|
|
60
66
|
|
61
67
|
describe 'when Module or Class is key' do
|
62
68
|
before do
|
63
|
-
@class = Class.new
|
69
|
+
@class = Class.new
|
64
70
|
@class.class_eval do
|
71
|
+
include ClassX
|
72
|
+
|
65
73
|
has :x, :isa => Integer, :coerce => { String => proc {|val| val.to_i } }
|
66
74
|
end
|
67
75
|
end
|
data/spec/classx/with_extend.rb
CHANGED
@@ -5,7 +5,7 @@ describe ClassX do
|
|
5
5
|
describe '#has' do
|
6
6
|
describe 'with extend' do
|
7
7
|
before do
|
8
|
-
@class = Class.new
|
8
|
+
@class = Class.new
|
9
9
|
mod = Module.new
|
10
10
|
mod.module_eval do
|
11
11
|
define_method :test do
|
@@ -13,6 +13,8 @@ describe ClassX do
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
@class.class_eval do
|
16
|
+
include ClassX
|
17
|
+
|
16
18
|
has :x, :extend => mod
|
17
19
|
end
|
18
20
|
end
|