mpatch 2.3.0 → 2.4.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.
- 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
|