mpatch 2.3.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +92 -42
- data/VERSION +1 -1
- data/examples/test.rb +6 -3
- data/lib/mpatch/all.rb +7 -0
- data/lib/mpatch/array.rb +123 -115
- data/lib/mpatch/class.rb +75 -66
- data/lib/mpatch/hash.rb +100 -91
- data/lib/mpatch/injector.rb +62 -0
- data/lib/mpatch/integer.rb +15 -7
- data/lib/mpatch/module.rb +56 -45
- data/lib/mpatch/object.rb +127 -118
- data/lib/mpatch/proc.rb +19 -10
- data/lib/mpatch/process.rb +18 -9
- data/lib/mpatch/random.rb +34 -25
- data/lib/mpatch/string.rb +73 -64
- data/lib/mpatch/yml.rb +14 -7
- data/lib/mpatch.rb +1 -44
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 09f45571e4ead5c5407a50275bcca9b13316b3b1
|
4
|
+
data.tar.gz: 79afe3c73630cb5124c58967e9dafc790efa665c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e47dcb190075aab9e175dc9a02d3cc68d9d77a9a6785154541f8280f6959c2b8bda5468e0aaa5541c3b21b87668917056edb36942bfb1d811a229b6621078ac4
|
7
|
+
data.tar.gz: 256612b44b53b3d28f8f2f69e7a01651a0c312cdd864e0aeac1fae56b21980ffa6fe080cf06e483066af53c88a9ed19693a86fab94b409fc2667bb5630b7caa2
|
data/README.md
CHANGED
@@ -3,75 +3,125 @@ mpatch
|
|
3
3
|
|
4
4
|
Monkey patch collection for advance helper functions
|
5
5
|
|
6
|
-
This project aim to give flexible methods to the developer by giving new inheritance to the base classes
|
6
|
+
This project aim to give flexible methods to the developer by giving new methods by inheritance to the base classes.
|
7
|
+
This will result in lot of helper methods, and metaprograming tricks
|
7
8
|
|
8
|
-
for example
|
9
9
|
|
10
|
-
|
10
|
+
### Install
|
11
11
|
|
12
|
-
|
12
|
+
gem install mpatch
|
13
13
|
|
14
|
-
|
14
|
+
### Use
|
15
15
|
|
16
|
-
|
16
|
+
```ruby
|
17
|
+
# load and patch all
|
18
|
+
require 'mpatch'
|
19
|
+
```
|
17
20
|
|
18
|
-
@hello= "world"
|
19
|
-
@sup= "nothing"
|
20
21
|
|
21
|
-
|
22
|
+
### example with Class methods
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
require 'mpatch'
|
26
|
+
|
27
|
+
class Test
|
28
|
+
|
29
|
+
def initialize
|
30
|
+
|
31
|
+
@hello= "world"
|
32
|
+
@sup= "nothing"
|
22
33
|
|
23
|
-
end
|
34
|
+
end
|
24
35
|
|
25
|
-
|
26
|
-
|
27
|
-
|
36
|
+
end
|
37
|
+
|
38
|
+
puts Test.new.convert_to_hash
|
39
|
+
#> {"hello" => "world", "sup" => "nothing"}
|
40
|
+
```
|
28
41
|
|
29
42
|
The module give you tools in your hand for inheritance handle.
|
30
43
|
For example:
|
31
44
|
|
32
|
-
|
33
|
-
puts Models::MongoidClassName.mixin_ancestors.include? Mongoid::Document
|
34
|
-
#> true
|
45
|
+
```ruby
|
46
|
+
puts Models::MongoidClassName.mixin_ancestors.include? Mongoid::Document
|
47
|
+
#> true
|
35
48
|
|
36
|
-
puts Mongoid::Document.inherited_by.inspect
|
37
|
-
#> [MongoidClassName]
|
49
|
+
puts Mongoid::Document.inherited_by.inspect
|
50
|
+
#> [MongoidClassName]
|
38
51
|
|
39
|
-
class Test
|
52
|
+
class Test
|
40
53
|
|
41
|
-
end
|
54
|
+
end
|
42
55
|
|
43
|
-
module Hello
|
44
|
-
|
45
|
-
|
46
|
-
end
|
56
|
+
module Hello
|
57
|
+
class World < Test
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
puts Test.inherited_by.inspect
|
62
|
+
#> [Hello::World]
|
63
|
+
|
64
|
+
module ParentModule
|
65
|
+
|
66
|
+
end
|
47
67
|
|
48
|
-
|
49
|
-
|
68
|
+
module TargetModule
|
69
|
+
include ParentModule
|
70
|
+
end
|
50
71
|
|
51
|
-
module
|
72
|
+
module SomeModuleThatInclude
|
73
|
+
include TargetModule
|
74
|
+
end
|
52
75
|
|
53
|
-
|
76
|
+
class SomeClassThatInclude
|
77
|
+
include TargetModule
|
78
|
+
end
|
54
79
|
|
55
|
-
|
56
|
-
|
57
|
-
end
|
80
|
+
puts TargetModule.inherited_by.inspect
|
81
|
+
#>[SomeClassThatInclude, SomeModuleThatInclude]
|
58
82
|
|
59
|
-
|
60
|
-
|
61
|
-
|
83
|
+
puts TargetModule.inherited_by(Class).inspect
|
84
|
+
#>[SomeClassThatInclude]
|
85
|
+
```
|
62
86
|
|
63
|
-
|
64
|
-
include TargetModule
|
65
|
-
end
|
87
|
+
### require for use only
|
66
88
|
|
67
|
-
|
68
|
-
|
89
|
+
```ruby
|
90
|
+
require File.join 'mpatch','array' # == require 'mpatch/array' but works on windows alike
|
69
91
|
|
70
|
-
|
71
|
-
|
92
|
+
# sugar syntax
|
93
|
+
# in this case it will help you with Array class for the following
|
94
|
+
#
|
95
|
+
# Array.__send__ :include/:extend , ::MPatch::Module::Name
|
96
|
+
#
|
97
|
+
# it will always choose include or extend method based on the module use porpuse
|
98
|
+
# now it's a :include
|
72
99
|
|
73
|
-
|
100
|
+
MPatch.patch! # || inject_patches || inject
|
101
|
+
puts ["asd"].has_any_of?(%W[ 123 hello\ world sup? asd ])
|
102
|
+
```
|
103
|
+
|
104
|
+
### make your own!
|
105
|
+
|
106
|
+
you can make your own monkey patches by the following
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
module MPatch
|
110
|
+
|
111
|
+
module Include # if you want to include to the target object
|
112
|
+
|
113
|
+
module TargetClassName #> for example Array
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
74
120
|
|
121
|
+
MPatch.patch!
|
122
|
+
# done, you all set
|
123
|
+
# if you want to contribute with use cases, please do so! :)
|
124
|
+
```
|
75
125
|
|
76
126
|
But there is a lot of method, for example for modules modules / subbmodules call that retunr modules under that namespace.
|
77
127
|
Lot of metaprogrammer stuff there too :)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.4.0
|
data/examples/test.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
require 'mpatch'
|
1
|
+
require File.join 'mpatch','array'
|
2
|
+
MPatch.patch!
|
2
3
|
|
3
|
-
puts
|
4
|
-
|
4
|
+
puts ["asd"].has_any_of?(%W[ 123 hello\ world sup? asd])
|
5
|
+
|
6
|
+
require File.join 'mpatch' # require and patch all
|
7
|
+
puts Object.ancestors.inspect
|
data/lib/mpatch/all.rb
ADDED
data/lib/mpatch/array.rb
CHANGED
@@ -1,154 +1,162 @@
|
|
1
|
-
module MPatch
|
1
|
+
module MPatch
|
2
2
|
|
3
|
-
module
|
3
|
+
module Include
|
4
4
|
|
5
|
-
|
6
|
-
# parameters from the main array
|
7
|
-
def trim(*args)
|
5
|
+
module Array
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
args= args+one_element
|
13
|
-
end
|
14
|
-
end
|
7
|
+
# remove arguments or array of
|
8
|
+
# parameters from the main array
|
9
|
+
def trim(*args)
|
15
10
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
self.delete_at(index)
|
11
|
+
args.dup.each do |one_element|
|
12
|
+
if one_element.class <= ::Array
|
13
|
+
args.delete_at(args.index(one_element))
|
14
|
+
args= args+one_element
|
15
|
+
end
|
22
16
|
end
|
23
|
-
end
|
24
17
|
|
25
|
-
|
26
|
-
|
27
|
-
|
18
|
+
delete_array= self.class.new
|
19
|
+
args.each do |one_element|
|
20
|
+
index= self.index(one_element)
|
21
|
+
unless index.nil?
|
22
|
+
delete_array.push index
|
23
|
+
self.delete_at(index)
|
24
|
+
end
|
25
|
+
end
|
28
26
|
|
29
|
-
|
30
|
-
def index_of(target_element)
|
31
|
-
array = self
|
32
|
-
hash = ::Hash[array.map.with_index.to_a]
|
33
|
-
return hash[target_element]
|
34
|
-
end
|
27
|
+
return self
|
35
28
|
|
36
|
-
|
37
|
-
# and return a new object
|
38
|
-
def pinch n=1
|
39
|
-
return self[0..(self.count-(n+1))]
|
40
|
-
end
|
29
|
+
end
|
41
30
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
31
|
+
# return index of the target element
|
32
|
+
def index_of(target_element)
|
33
|
+
array = self
|
34
|
+
hash = ::Hash[array.map.with_index.to_a]
|
35
|
+
return hash[target_element]
|
47
36
|
end
|
48
|
-
return self
|
49
|
-
end
|
50
37
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
38
|
+
# remove n. element from the end
|
39
|
+
# and return a new object
|
40
|
+
def pinch n=1
|
41
|
+
return self[0..(self.count-(n+1))]
|
42
|
+
end
|
57
43
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
if self.include? element
|
64
|
-
return true
|
44
|
+
# remove n. element from the end
|
45
|
+
# and return the original object
|
46
|
+
def pinch! n=1
|
47
|
+
n.times do
|
48
|
+
self.pop
|
65
49
|
end
|
50
|
+
return self
|
66
51
|
end
|
67
|
-
return false
|
68
|
-
end
|
69
52
|
|
70
|
-
|
71
|
-
|
53
|
+
# return boolean by other array
|
54
|
+
# all element included or
|
55
|
+
# not in the target array
|
56
|
+
def contain?(oth_array)#anothere array
|
57
|
+
(oth_array & self) == oth_array
|
58
|
+
end
|
72
59
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
60
|
+
# return boolean by other array
|
61
|
+
# if any element included from
|
62
|
+
# the oth_array, return a true
|
63
|
+
def contain_any_of?(oth_array)
|
64
|
+
oth_array.each do |element|
|
65
|
+
if self.include? element
|
66
|
+
return true
|
67
|
+
end
|
68
|
+
end
|
69
|
+
return false
|
80
70
|
end
|
81
|
-
result
|
82
|
-
end
|
83
71
|
|
84
|
-
|
72
|
+
alias :contains_any_of? :contain_any_of?
|
73
|
+
alias :has_any_of? :contain_any_of?
|
85
74
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
return true
|
75
|
+
# do safe transpose
|
76
|
+
def safe_transpose
|
77
|
+
result = []
|
78
|
+
max_size = self.max { |a,b| a.size <=> b.size }.size
|
79
|
+
max_size.times do |i|
|
80
|
+
result[i] = self.class.new(self.first.size)
|
81
|
+
self.each_with_index { |r,j| result[i][j] = r[i] }
|
82
|
+
end
|
83
|
+
result
|
96
84
|
end
|
97
|
-
return false
|
98
|
-
end
|
99
|
-
|
100
|
-
alias :contains_element_of_class? :contain_element_of_class?
|
101
|
-
alias :has_element_of_class? :contain_element_of_class?
|
102
85
|
|
103
|
-
|
104
|
-
# *args => [:opts,:args]
|
105
|
-
def params_separation
|
86
|
+
alias :contains? :contain?
|
106
87
|
|
107
|
-
|
108
|
-
|
109
|
-
|
88
|
+
# return boolean
|
89
|
+
# if any element class is equal to th given class
|
90
|
+
# return a true , else false
|
91
|
+
def contain_element_of_class?(class_name)
|
92
|
+
target_array= self.map{|e| e.class }.uniq
|
93
|
+
if class_name.class != ::Class
|
94
|
+
raise ::ArgumentError, "Argument must be a Class!"
|
95
|
+
end
|
96
|
+
if target_array.include? class_name
|
97
|
+
return true
|
110
98
|
end
|
111
|
-
|
112
|
-
|
113
|
-
arguments= self.dup - options
|
114
|
-
options= ::Hash[*options]
|
99
|
+
return false
|
100
|
+
end
|
115
101
|
|
116
|
-
|
102
|
+
alias :contains_element_of_class? :contain_element_of_class?
|
103
|
+
alias :has_element_of_class? :contain_element_of_class?
|
117
104
|
|
118
|
-
|
105
|
+
# generate params structure from array
|
106
|
+
# *args => [:opts,:args]
|
107
|
+
def params_separation
|
119
108
|
|
120
|
-
|
121
|
-
|
109
|
+
options= self.map { |element|
|
110
|
+
if element.class == ::Hash
|
111
|
+
element
|
112
|
+
end
|
113
|
+
}.uniq - [ nil ]
|
114
|
+
#options.each{|e| self.delete(e) }
|
115
|
+
arguments= self.dup - options
|
116
|
+
options= ::Hash[*options]
|
122
117
|
|
123
|
-
|
124
|
-
# return_array
|
125
|
-
def extract_class! class_name
|
118
|
+
return [options,arguments]
|
126
119
|
|
127
|
-
unless class_name.class <= ::Class
|
128
|
-
raise ::ArgumentError, "parameter must be a class name"
|
129
120
|
end
|
130
121
|
|
131
|
-
|
132
|
-
|
133
|
-
|
122
|
+
alias :separate_params :params_separation
|
123
|
+
alias :process_params :params_separation
|
124
|
+
|
125
|
+
# generate params structure from array
|
126
|
+
# return_array
|
127
|
+
def extract_class! class_name
|
128
|
+
|
129
|
+
unless class_name.class <= ::Class
|
130
|
+
raise ::ArgumentError, "parameter must be a class name"
|
134
131
|
end
|
135
|
-
}.uniq - [ nil ]
|
136
|
-
return_value.each{|e| self.delete(e) }
|
137
132
|
|
138
|
-
|
133
|
+
return_value= self.map { |element|
|
134
|
+
if element.class <= class_name
|
135
|
+
element
|
136
|
+
end
|
137
|
+
}.uniq - [ nil ]
|
138
|
+
return_value.each{|e| self.delete(e) }
|
139
139
|
|
140
|
-
|
140
|
+
return_value ||= self.class.new
|
141
141
|
|
142
|
-
|
143
|
-
|
142
|
+
return return_value
|
143
|
+
|
144
|
+
end
|
145
|
+
alias :cut_class! :extract_class!
|
146
|
+
|
147
|
+
# generate params structure from array
|
148
|
+
# *args - options {}
|
149
|
+
def extract_options!
|
150
|
+
options= self.extract_class! ::Hash
|
151
|
+
return ::Hash[*options]
|
152
|
+
end
|
153
|
+
alias :extract_hash! :extract_options!
|
144
154
|
|
145
|
-
# generate params structure from array
|
146
|
-
# *args - options {}
|
147
|
-
def extract_options!
|
148
|
-
options= self.extract_class! ::Hash
|
149
|
-
return ::Hash[*options]
|
150
155
|
end
|
151
|
-
alias :extract_hash! :extract_options!
|
152
156
|
|
153
157
|
end
|
158
|
+
|
159
|
+
require File.join 'mpatch','injector'
|
160
|
+
|
161
|
+
|
154
162
|
end
|
data/lib/mpatch/class.rb
CHANGED
@@ -1,94 +1,103 @@
|
|
1
|
-
module MPatch
|
2
|
-
module Class
|
1
|
+
module MPatch
|
3
2
|
|
4
|
-
|
5
|
-
def class_methods
|
6
|
-
self.methods - ::Object.methods
|
7
|
-
end
|
3
|
+
module Include
|
8
4
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
5
|
+
module Class
|
6
|
+
|
7
|
+
# get singleton methods to target class without super class methods
|
8
|
+
def class_methods
|
9
|
+
self.methods - ::Object.methods
|
15
10
|
end
|
16
|
-
end
|
17
11
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
12
|
+
# bind a singleton method to a class object
|
13
|
+
def create_class_method(method,&block)
|
14
|
+
self.class_eval do
|
15
|
+
define_singleton_method method do |*args|
|
16
|
+
block.call *args
|
17
|
+
end
|
23
18
|
end
|
24
19
|
end
|
25
|
-
end
|
26
20
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
# comparison of Class with Class failed (ArgumentError)
|
21
|
+
# create an instance method
|
22
|
+
def create_instance_method(method,&block)
|
23
|
+
self.class_eval do
|
24
|
+
define_method method do |*args|
|
25
|
+
block.call *args
|
26
|
+
end
|
34
27
|
end
|
35
|
-
|
36
|
-
end
|
28
|
+
end
|
37
29
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
30
|
+
# Iterates over all subclasses (direct and indirect)
|
31
|
+
def each_subclass
|
32
|
+
::ObjectSpace.each_object(::Class) { | candidate |
|
33
|
+
begin
|
34
|
+
yield candidate if candidate < self
|
35
|
+
rescue ::ArgumentError
|
36
|
+
# comparison of Class with Class failed (ArgumentError)
|
37
|
+
end
|
38
|
+
}
|
39
|
+
end
|
44
40
|
|
45
|
-
|
41
|
+
# Returns an Array of subclasses (direct and indirect)
|
42
|
+
def subclasses_all
|
43
|
+
ret = []
|
44
|
+
each_subclass {|c| ret.push c}
|
45
|
+
ret
|
46
|
+
end
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
48
|
+
alias :all_subclasses :subclasses_all
|
49
|
+
|
50
|
+
# Returns an Array of direct subclasses
|
51
|
+
def subclasses
|
52
|
+
ret = []
|
53
|
+
each_subclass {|c| ret.push(c) if c.superclass == self }
|
54
|
+
ret
|
55
|
+
end
|
56
|
+
alias :subclass :subclasses
|
54
57
|
|
55
|
-
|
56
|
-
|
58
|
+
# create singleton attribute
|
59
|
+
def class_attr_accessor(name)
|
57
60
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
61
|
+
### GET
|
62
|
+
begin
|
63
|
+
define_method name do
|
64
|
+
class_variable_get "@@#{name}"
|
65
|
+
end
|
62
66
|
end
|
63
|
-
end
|
64
67
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
68
|
+
### SET
|
69
|
+
begin
|
70
|
+
define_method "#{name}=" do |new_val|
|
71
|
+
class_variable_set "@@#{name}", new_val
|
72
|
+
end
|
69
73
|
end
|
70
|
-
end
|
71
74
|
|
72
|
-
|
75
|
+
end
|
73
76
|
|
74
|
-
|
75
|
-
|
77
|
+
# create class instance attribute
|
78
|
+
def instance_attr_accessor(name)
|
76
79
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
80
|
+
### GET
|
81
|
+
begin
|
82
|
+
define_method name do
|
83
|
+
instance_variable_get "@#{name}"
|
84
|
+
end
|
81
85
|
end
|
82
|
-
end
|
83
86
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
87
|
+
### SET
|
88
|
+
begin
|
89
|
+
define_method "#{name}=" do |new_val|
|
90
|
+
instance_variable_set "@#{name}", new_val
|
91
|
+
end
|
88
92
|
end
|
93
|
+
|
89
94
|
end
|
90
95
|
|
91
96
|
end
|
92
97
|
|
93
98
|
end
|
99
|
+
|
100
|
+
require File.join 'mpatch','injector'
|
101
|
+
|
102
|
+
|
94
103
|
end
|