ruby_ext 0.4.6
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/Rakefile +64 -0
- data/lib/ruby_ext/array.rb +13 -0
- data/lib/ruby_ext/basic_object.rb +22 -0
- data/lib/ruby_ext/class.rb +11 -0
- data/lib/ruby_ext/declarative_cache.rb +85 -0
- data/lib/ruby_ext/deep_clone.rb +62 -0
- data/lib/ruby_ext/extra_blank_slate.rb +16 -0
- data/lib/ruby_ext/file.rb +20 -0
- data/lib/ruby_ext/hash.rb +15 -0
- data/lib/ruby_ext/kernel.rb +69 -0
- data/lib/ruby_ext/micelaneous.rb +14 -0
- data/lib/ruby_ext/module.rb +119 -0
- data/lib/ruby_ext/multiple_inheritance.rb +76 -0
- data/lib/ruby_ext/must.rb +192 -0
- data/lib/ruby_ext/not_defined.rb +2 -0
- data/lib/ruby_ext/object.rb +8 -0
- data/lib/ruby_ext/observable2.rb +23 -0
- data/lib/ruby_ext/open_constructor.rb +51 -0
- data/lib/ruby_ext/open_object.rb +157 -0
- data/lib/ruby_ext/prepare_arguments.rb +105 -0
- data/lib/ruby_ext/prototype_inheritance.rb +110 -0
- data/lib/ruby_ext/should.rb +166 -0
- data/lib/ruby_ext/string.rb +44 -0
- data/lib/ruby_ext/symbol.rb +21 -0
- data/lib/ruby_ext/synchronize.rb +24 -0
- data/lib/ruby_ext/tuple.rb +7 -0
- data/lib/ruby_ext.rb +50 -0
- data/lib/spec_ext.rb +10 -0
- data/readme.md +66 -0
- data/spec/_prototype_inheritance_spec.rb +190 -0
- data/spec/array_spec.rb +8 -0
- data/spec/declarative_cache_spec.rb +115 -0
- data/spec/deep_clone_spec.rb +37 -0
- data/spec/helper.rb +20 -0
- data/spec/kernel_spec/TheNamespace/ClassA.rb +7 -0
- data/spec/kernel_spec/another_class.rb +5 -0
- data/spec/kernel_spec/the_namespace/class_b.rb +11 -0
- data/spec/kernel_spec.rb +53 -0
- data/spec/module_spec.rb +160 -0
- data/spec/multiple_inheritance_spec.rb +131 -0
- data/spec/must_spec.rb +29 -0
- data/spec/observable2_spec.rb +42 -0
- data/spec/open_constructor_spec.rb +36 -0
- data/spec/open_object_spec.rb +29 -0
- data/spec/prepare_arguments_spec.rb +46 -0
- data/spec/should_spec.rb +24 -0
- data/spec/spec.opts +2 -0
- data/spec/synchronize_spec.rb +80 -0
- metadata +127 -0
@@ -0,0 +1,192 @@
|
|
1
|
+
class AssertionError < StandardError; end
|
2
|
+
|
3
|
+
class MustAssertions < ExtraBlankSlate
|
4
|
+
attr_reader :obj
|
5
|
+
|
6
|
+
def initialize obj
|
7
|
+
@obj = obj
|
8
|
+
end
|
9
|
+
|
10
|
+
def == o
|
11
|
+
@obj == o
|
12
|
+
end
|
13
|
+
|
14
|
+
def =~ o
|
15
|
+
@obj =~ o
|
16
|
+
end
|
17
|
+
|
18
|
+
def never_called
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
def nil
|
23
|
+
@obj.equal? nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def defined
|
27
|
+
!nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def respond_to method
|
31
|
+
@obj.respond_to? method
|
32
|
+
end
|
33
|
+
|
34
|
+
def a klass
|
35
|
+
if klass.class == Array
|
36
|
+
klass.any?{|k| @obj.is_a? k}
|
37
|
+
else
|
38
|
+
@obj.is_a? klass
|
39
|
+
end
|
40
|
+
end
|
41
|
+
alias_method :an, :a
|
42
|
+
|
43
|
+
# def be klass = nil
|
44
|
+
# if klass.class == Array
|
45
|
+
# klass.any?{|k| @obj.respond_to :is?, k}
|
46
|
+
# else
|
47
|
+
# @obj.respond_to :is?, klass
|
48
|
+
# end
|
49
|
+
# end
|
50
|
+
|
51
|
+
def include o
|
52
|
+
@obj.include? o
|
53
|
+
end
|
54
|
+
|
55
|
+
def in *args
|
56
|
+
if args.size == 1
|
57
|
+
obj = args.first
|
58
|
+
if obj.is_a?(Array) or obj.is_a?(Range)
|
59
|
+
obj.include? @obj
|
60
|
+
else
|
61
|
+
args.include? @obj
|
62
|
+
end
|
63
|
+
else
|
64
|
+
args.include? @obj
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def true
|
69
|
+
!!@obj
|
70
|
+
end
|
71
|
+
|
72
|
+
def false
|
73
|
+
!@obj
|
74
|
+
end
|
75
|
+
|
76
|
+
def empty
|
77
|
+
@obj.empty?
|
78
|
+
end
|
79
|
+
|
80
|
+
def blank
|
81
|
+
@obj.blank?
|
82
|
+
end
|
83
|
+
|
84
|
+
def present
|
85
|
+
!@obj.blank?
|
86
|
+
end
|
87
|
+
|
88
|
+
def > o
|
89
|
+
@obj > o
|
90
|
+
end
|
91
|
+
|
92
|
+
def < o
|
93
|
+
@obj < o
|
94
|
+
end
|
95
|
+
|
96
|
+
def >= o
|
97
|
+
@obj >= o
|
98
|
+
end
|
99
|
+
|
100
|
+
def <= o
|
101
|
+
@obj <= o
|
102
|
+
end
|
103
|
+
|
104
|
+
def exist arg
|
105
|
+
@obj.exist? arg
|
106
|
+
end
|
107
|
+
|
108
|
+
def be
|
109
|
+
@prefix = 'be'
|
110
|
+
self
|
111
|
+
end
|
112
|
+
|
113
|
+
def have
|
114
|
+
@prefix = 'have'
|
115
|
+
self
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.assertions
|
119
|
+
special = %w{be have}
|
120
|
+
instance_methods.select{|m| m !~ /^__/ and m != 'be'}
|
121
|
+
end
|
122
|
+
|
123
|
+
protected
|
124
|
+
def method_missing m, *args, &b
|
125
|
+
raise RuntimeError, "Assertion '#{m}' is unknown!", caller[1..-1]
|
126
|
+
end
|
127
|
+
|
128
|
+
def failed method, negative, *args
|
129
|
+
stack = caller.sfilter('must.rb')
|
130
|
+
|
131
|
+
unless args.empty?
|
132
|
+
Kernel.raise AssertionError, "
|
133
|
+
ASSERTION FAILED (#{stack.first}):
|
134
|
+
#{@obj.inspect} must #{'not ' if negative}#{"#{@prefix} " if @prefix}#{method} #{args.first.inspect}
|
135
|
+
", stack
|
136
|
+
else
|
137
|
+
Kernel.raise AssertionError, "
|
138
|
+
ASSERTION FAILED (#{stack.first}):
|
139
|
+
#{@obj.inspect} must #{'not ' if negative}#{"#{@prefix} " if @prefix}#{method}
|
140
|
+
", stack
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
class Must < MustAssertions
|
146
|
+
assertions.each do |m|
|
147
|
+
desition = "_#{m}"
|
148
|
+
alias_method desition, m
|
149
|
+
define_method m do |*args|
|
150
|
+
failed m, false, *args unless __send__(desition, *args)
|
151
|
+
@obj
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
class MustNot < MustAssertions
|
157
|
+
assertions.each do |m|
|
158
|
+
desition = "_#{m}"
|
159
|
+
alias_method desition, m
|
160
|
+
define_method m do |*args|
|
161
|
+
failed m, true, *args if __send__(desition, *args)
|
162
|
+
@obj
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
Object.class_eval do
|
168
|
+
|
169
|
+
def must
|
170
|
+
Must.new(self)
|
171
|
+
end
|
172
|
+
|
173
|
+
def must_not
|
174
|
+
MustNot.new(self)
|
175
|
+
end
|
176
|
+
|
177
|
+
def must_be
|
178
|
+
must.be
|
179
|
+
end
|
180
|
+
|
181
|
+
def must_not_be
|
182
|
+
must_not.be
|
183
|
+
end
|
184
|
+
|
185
|
+
# def must_have
|
186
|
+
# must.have
|
187
|
+
# end
|
188
|
+
#
|
189
|
+
# def must_not_have
|
190
|
+
# must_not.have
|
191
|
+
# end
|
192
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Observable2
|
2
|
+
def add_observer observer
|
3
|
+
@observable_observers ||= []
|
4
|
+
@observable_observers << observer unless @observable_observers.include? observer
|
5
|
+
end
|
6
|
+
|
7
|
+
def notify_observers method, *args
|
8
|
+
raise "Invalid usage, method must be Symbol or String!" unless method.is_a?(Symbol) or method.is_a?(String)
|
9
|
+
@observable_observers.each{|observer| observer.respond_to method, *args} if @observable_observers
|
10
|
+
end
|
11
|
+
|
12
|
+
def delete_observer observer
|
13
|
+
@observable_observers.delete observer if @observable_observers
|
14
|
+
end
|
15
|
+
|
16
|
+
def delete_observers
|
17
|
+
@observable_observers.clear if @observable_observers
|
18
|
+
end
|
19
|
+
|
20
|
+
def observers_count
|
21
|
+
@observable_observers ? @observable_observers.size : 0
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module OpenConstructor
|
2
|
+
def set values, list = nil
|
3
|
+
unless list
|
4
|
+
if values.is_a? Hash
|
5
|
+
values.each do |k, v|
|
6
|
+
self.respond_to k.to_writer, v
|
7
|
+
end
|
8
|
+
else
|
9
|
+
values.instance_variables.each do |name|
|
10
|
+
accessor = name[1..name.size].to_writer
|
11
|
+
if self.respond_to? accessor
|
12
|
+
self.send accessor, values.instance_variable_get(name)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
else
|
17
|
+
if values.is_a? Hash
|
18
|
+
values.each do |k, v|
|
19
|
+
self.respond_to k.to_writer, v if list.include? k
|
20
|
+
end
|
21
|
+
else
|
22
|
+
values.instance_variables.each do |name|
|
23
|
+
accessor = name[1..name.size]
|
24
|
+
if list.include?(accessor.to_sym)
|
25
|
+
accessor = accessor.to_writer
|
26
|
+
if self.respond_to?(accessor)
|
27
|
+
self.send accessor, values.instance_variable_get(name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
return self
|
34
|
+
end
|
35
|
+
|
36
|
+
def set_with_check values
|
37
|
+
values.each do |k, v|
|
38
|
+
self.send k.to_writer, v
|
39
|
+
end
|
40
|
+
return self
|
41
|
+
end
|
42
|
+
alias_method :set!, :set_with_check
|
43
|
+
|
44
|
+
def to_hash
|
45
|
+
hash = {}
|
46
|
+
instance_variables.each do |name|
|
47
|
+
hash[name[1..name.size].to_sym] = instance_variable_get name
|
48
|
+
end
|
49
|
+
return hash
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
raise "You shouldn't use OpenObject defined in facets, it's incopatible with this version!" if defined?(OpenObject)
|
2
|
+
|
3
|
+
class OpenObject < Hash
|
4
|
+
|
5
|
+
PUBLIC_METHODS = %w(as send each size is_a? clone dup empty? blank? present? merge merge! stringify_keys stringify_keys! symbolize_keys symbolize_keys! to_query)
|
6
|
+
PUBLIC_METHODS_RE = /(^__|^object_)/
|
7
|
+
|
8
|
+
protected(*public_instance_methods.select{ |m| !PUBLIC_METHODS.include?(m) and m !~ PUBLIC_METHODS_RE })
|
9
|
+
|
10
|
+
def inspect
|
11
|
+
"#<#{self.class}:#{self.object_id} #{super}>"
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_a; super end
|
15
|
+
|
16
|
+
def to_proc; super end
|
17
|
+
|
18
|
+
def to_openobject deep = false
|
19
|
+
unless deep
|
20
|
+
self
|
21
|
+
else
|
22
|
+
r = OpenObject.new
|
23
|
+
each do |k, v|
|
24
|
+
r[k] = if v.is_a? Hash
|
25
|
+
v.to_openobject
|
26
|
+
else
|
27
|
+
v
|
28
|
+
end
|
29
|
+
end
|
30
|
+
r
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def each █ super(&block) end
|
35
|
+
|
36
|
+
def merge other
|
37
|
+
d = dup
|
38
|
+
other.each{|k, v| d[k] = v}
|
39
|
+
d
|
40
|
+
# d = dup
|
41
|
+
# d.send(:update, other)
|
42
|
+
# d
|
43
|
+
end
|
44
|
+
|
45
|
+
def merge! other
|
46
|
+
other.each{|k, v| self[k] = v}
|
47
|
+
end
|
48
|
+
|
49
|
+
def update other
|
50
|
+
other.to_hash.each{|k,v| self[k.to_s] = v}
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def delete key
|
55
|
+
super key.to_s
|
56
|
+
end
|
57
|
+
|
58
|
+
def == other
|
59
|
+
return false unless other.respond_to?(:each) and other.respond_to?(:size) and other.respond_to?(:[]) and self.size == other.size
|
60
|
+
other.each do |k, v|
|
61
|
+
return false unless self[k] == v
|
62
|
+
end
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
66
|
+
def []= k, v
|
67
|
+
super k.to_s, v
|
68
|
+
end
|
69
|
+
|
70
|
+
def [] k
|
71
|
+
super k.to_s
|
72
|
+
end
|
73
|
+
|
74
|
+
def include? k
|
75
|
+
super k.to_s
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_hash deep = false
|
79
|
+
unless deep
|
80
|
+
{}.update(self)
|
81
|
+
else
|
82
|
+
h = {}
|
83
|
+
each do |k, v|
|
84
|
+
if v.is_a? OpenObject
|
85
|
+
h[k] = v.to_hash(true)
|
86
|
+
else
|
87
|
+
h[k] = v
|
88
|
+
end
|
89
|
+
end
|
90
|
+
h
|
91
|
+
end
|
92
|
+
end
|
93
|
+
alias_method :to_h, :to_hash
|
94
|
+
|
95
|
+
def to_json *args
|
96
|
+
to_hash.to_json *args
|
97
|
+
end
|
98
|
+
|
99
|
+
# hack to works well with RSpec
|
100
|
+
def should; super end
|
101
|
+
def should_not; super end
|
102
|
+
|
103
|
+
def respond_to? m
|
104
|
+
true
|
105
|
+
end
|
106
|
+
|
107
|
+
protected
|
108
|
+
def method_missing m, arg = nil, &block
|
109
|
+
m = m.to_s
|
110
|
+
type = m[-1,1]
|
111
|
+
# key = m.to_s.sub(/[=?!]$/,'').to_s
|
112
|
+
if type == '='
|
113
|
+
self[m[0..-2]] = arg
|
114
|
+
elsif type == '!'
|
115
|
+
self[m[0..-2]]
|
116
|
+
elsif type == '?'
|
117
|
+
!self[m[0..-2]].blank?
|
118
|
+
else
|
119
|
+
self[m]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
#
|
126
|
+
# Core Extensions
|
127
|
+
#
|
128
|
+
class NilClass
|
129
|
+
def to_openobject deep = false
|
130
|
+
OpenObject.new
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class Hash
|
135
|
+
def to_openobject deep = false
|
136
|
+
unless deep
|
137
|
+
OpenObject.new.update self
|
138
|
+
else
|
139
|
+
r = OpenObject.new
|
140
|
+
each do |k, v|
|
141
|
+
r[k] = if v.is_a? Hash
|
142
|
+
v.to_openobject
|
143
|
+
else
|
144
|
+
v
|
145
|
+
end
|
146
|
+
end
|
147
|
+
r
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
alias_method :oo_eql, :==
|
152
|
+
def == other
|
153
|
+
true if self.equal? other
|
154
|
+
other == self if other.is_a? OpenObject
|
155
|
+
oo_eql other
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
class ArgumentsParser
|
2
|
+
class << self
|
3
|
+
def register method, arguments
|
4
|
+
# check and prepare metadata
|
5
|
+
arguments.collect!{|meta| meta.is_a?(Hash) ? meta : {:type => meta}}
|
6
|
+
arguments.each{|meta| meta.must.include :type}
|
7
|
+
|
8
|
+
# register
|
9
|
+
@registry ||= {}
|
10
|
+
@registry[method] = arguments
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse_arguments_for method, *args, &block
|
14
|
+
metadata = @registry[method]
|
15
|
+
index = 0
|
16
|
+
parsed_args = metadata.collect do |options|
|
17
|
+
send options[:type], args, block, options, index, (index == metadata.size - 1)
|
18
|
+
end
|
19
|
+
args.must_be.empty
|
20
|
+
return parsed_args
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
def string args, block, options, index, last
|
25
|
+
object(args, block, options, index, last) || ""
|
26
|
+
end
|
27
|
+
|
28
|
+
def object args, block, options, index, last
|
29
|
+
a = if range = options[:range]
|
30
|
+
if range == :except_last_hash
|
31
|
+
if args.size == 1 and args.last.is_a? Hash
|
32
|
+
nil
|
33
|
+
else
|
34
|
+
args.shift
|
35
|
+
end
|
36
|
+
else
|
37
|
+
must_be.never_called
|
38
|
+
end
|
39
|
+
else
|
40
|
+
args.shift
|
41
|
+
end
|
42
|
+
|
43
|
+
a = _common_options a, options
|
44
|
+
a
|
45
|
+
end
|
46
|
+
|
47
|
+
def array args, block, options, index, last
|
48
|
+
a = if last
|
49
|
+
args
|
50
|
+
elsif range = options[:range]
|
51
|
+
if range == :except_last_hash
|
52
|
+
if args.last.is_a? Hash
|
53
|
+
tmp = args[0..-2]
|
54
|
+
args[0..-2] = nil
|
55
|
+
tmp
|
56
|
+
else
|
57
|
+
tmp = args[0..-1]
|
58
|
+
args.clear
|
59
|
+
tmp
|
60
|
+
end
|
61
|
+
else
|
62
|
+
must_be.never_called
|
63
|
+
end
|
64
|
+
else
|
65
|
+
args.shift
|
66
|
+
end
|
67
|
+
|
68
|
+
a = _common_options a, options
|
69
|
+
a ||= []
|
70
|
+
a = [a] unless a.is_a?(Array)
|
71
|
+
a
|
72
|
+
end
|
73
|
+
|
74
|
+
def hash args, block, options, index, last
|
75
|
+
a = object(args, block, options, index, last) || {}
|
76
|
+
a.must_be.a Hash
|
77
|
+
a
|
78
|
+
end
|
79
|
+
|
80
|
+
def _common_options a, options
|
81
|
+
a.must_not_be.nil if options[:require]
|
82
|
+
if (default = options[:default]) and a.eql?(nil)
|
83
|
+
a = default
|
84
|
+
end
|
85
|
+
a
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
Module.class_eval do
|
91
|
+
def prepare_arguments_for method, *args
|
92
|
+
# Register parsers
|
93
|
+
ArgumentsParser.register method, args
|
94
|
+
|
95
|
+
# Wrap method
|
96
|
+
old_method = :"#{method}_wparg"
|
97
|
+
alias_method old_method, method
|
98
|
+
code = <<END
|
99
|
+
def #{method} *args, &block
|
100
|
+
#{old_method} *ArgumentsParser.parse_arguments_for(:#{method}, *args), &block
|
101
|
+
end
|
102
|
+
END
|
103
|
+
class_eval code, __FILE__, __LINE__
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
#
|
2
|
+
# Fix for ruby's broken include.
|
3
|
+
# Included modules doesn't propagated to it's children.
|
4
|
+
#
|
5
|
+
# Test case:
|
6
|
+
# module A; end
|
7
|
+
# module B
|
8
|
+
# include A
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# module Plugin; end
|
12
|
+
# A.send(:include, Plugin)
|
13
|
+
#
|
14
|
+
# p "Ancestors of A: " + A.ancestors.join(', ') # => "Ancestors of A: A, Plugin"
|
15
|
+
# p "Ancestors of B: " + B.ancestors.join(', ') # => "Ancestors of B: B, A" << NO PLUGIN!
|
16
|
+
#
|
17
|
+
class Module
|
18
|
+
def directly_included_by
|
19
|
+
@directly_included_by ||= Set.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def fixed_include mod
|
23
|
+
unless mod.directly_included_by.include? self
|
24
|
+
mod.directly_included_by.add self
|
25
|
+
end
|
26
|
+
|
27
|
+
include mod
|
28
|
+
directly_included_by.each do |child|
|
29
|
+
child.fixed_include self
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
#
|
36
|
+
# Prototypes
|
37
|
+
#
|
38
|
+
class Class
|
39
|
+
def prototype
|
40
|
+
unless @prototype
|
41
|
+
unless const_defined? :Prototype
|
42
|
+
class_eval "module Prototype; end", __FILE__, __LINE__
|
43
|
+
end
|
44
|
+
@prototype = const_get :Prototype
|
45
|
+
|
46
|
+
fixed_include @prototype
|
47
|
+
end
|
48
|
+
@prototype
|
49
|
+
end
|
50
|
+
|
51
|
+
def class_prototype
|
52
|
+
unless @class_prototype
|
53
|
+
unless const_defined? :ClassPrototype
|
54
|
+
class_eval "module ClassPrototype; end", __FILE__, __LINE__
|
55
|
+
end
|
56
|
+
@class_prototype = const_get :ClassPrototype
|
57
|
+
|
58
|
+
(class << self; self end).fixed_include @class_prototype
|
59
|
+
end
|
60
|
+
@class_prototype
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
#
|
66
|
+
# Inheritance logic
|
67
|
+
#
|
68
|
+
class Class
|
69
|
+
def define_instance_methods &block
|
70
|
+
prototype.class_eval &block
|
71
|
+
# self.include prototype
|
72
|
+
end
|
73
|
+
|
74
|
+
def define_class_methods &block
|
75
|
+
self.class_prototype.class_eval &block
|
76
|
+
# self.extend self.class.prototype
|
77
|
+
end
|
78
|
+
|
79
|
+
def inherit *classes
|
80
|
+
classes.each do |klass|
|
81
|
+
raise "You can inherit classes only ('#{klass}')!" unless klass.class == Class
|
82
|
+
|
83
|
+
prototype.fixed_include klass.prototype
|
84
|
+
# self.include prototype
|
85
|
+
|
86
|
+
class_prototype.fixed_include klass.class_prototype
|
87
|
+
# (class << self; self end).include class_prototype
|
88
|
+
|
89
|
+
# callback
|
90
|
+
klass.inherited self if klass.respond_to? :inherited
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
#
|
97
|
+
# Sugar
|
98
|
+
#
|
99
|
+
Class.class_eval do
|
100
|
+
alias_method :instance_methods_without_prototype, :instance_methods
|
101
|
+
def instance_methods *args, &block
|
102
|
+
if block
|
103
|
+
define_instance_methods &block
|
104
|
+
else
|
105
|
+
instance_methods_without_prototype
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
alias_method :class_methods, :define_class_methods
|
110
|
+
end
|