cc 1.1.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 +7 -0
- data/LICENSE +21 -0
- data/LICENSE-CN.md +9 -0
- data/README.md +3 -0
- data/attribute.rb +71 -0
- data/cc.rb +43 -0
- data/chinese.rb +71 -0
- data/chrono.rb +162 -0
- data/enum.rb +47 -0
- data/exception.rb +91 -0
- data/file.rb +253 -0
- data/kernel.rb +227 -0
- data/monkey-patch.rb +116 -0
- data/number.rb +105 -0
- data/regexp.rb +23 -0
- data/string.rb +75 -0
- data/tree.rb +184 -0
- metadata +57 -0
data/file.rb
ADDED
@@ -0,0 +1,253 @@
|
|
1
|
+
#coding:utf-8
|
2
|
+
|
3
|
+
############################################################################################################
|
4
|
+
# HOW TO USE #
|
5
|
+
############################################################################################################
|
6
|
+
|
7
|
+
=begin
|
8
|
+
require 'cc'
|
9
|
+
CC.use 'file'
|
10
|
+
|
11
|
+
puts "The current directory:"
|
12
|
+
pp '..'.directory
|
13
|
+
|
14
|
+
puts '',"The filepaths under current directory:"
|
15
|
+
pp '..'.directory.paths
|
16
|
+
|
17
|
+
puts '',"The current directory whether include somewhere part of pathname:"
|
18
|
+
pp '..'.directory.find?(__FILE__)
|
19
|
+
|
20
|
+
tab1 = File.read("1/1.txt")
|
21
|
+
tab2 = File.read("2/1.txt")
|
22
|
+
text1 = Diff.shift tab1, 2.row, 1.row
|
23
|
+
text1 = Diff.shift text1, 5.line, 1.row
|
24
|
+
text1 = Diff.shift text1, 8.line, 2.rows
|
25
|
+
text2 = Diff.shift tab2, 7.row, 1.line
|
26
|
+
text2 = Diff.shift text2, 11.row, 1.line
|
27
|
+
tab = Diff.show text1, text2
|
28
|
+
File.write "tab.txt", tab.map{|t|t.join("|")}.join("\n")
|
29
|
+
|
30
|
+
File.diff('1/1.txt', '2/1.txt', 'tmp.diff', 'git diff')
|
31
|
+
File.diffs('1', '2', 'tmp.diff', 'git diff').save_into 'diff.txt'
|
32
|
+
=end
|
33
|
+
|
34
|
+
class String
|
35
|
+
# "PathString" => {FolderTree}
|
36
|
+
def directory_detection
|
37
|
+
folder = {}
|
38
|
+
Dir["#{self}/*"].each do|path|
|
39
|
+
next if ["..","."].include?(path)
|
40
|
+
epath = File.expand_path(path)
|
41
|
+
pathname = epath.split("/")[-1]
|
42
|
+
if File.directory?(epath)
|
43
|
+
sub = epath.directory_detection
|
44
|
+
folder.merge!(pathname=>sub) # epath
|
45
|
+
else
|
46
|
+
folder[pathname] = "file" # epath
|
47
|
+
end
|
48
|
+
end
|
49
|
+
return folder
|
50
|
+
end
|
51
|
+
|
52
|
+
alias :directory :directory_detection
|
53
|
+
|
54
|
+
def self.load_from path
|
55
|
+
buffer = File.open(path,'r'){|f|f.read}
|
56
|
+
if buffer.encoding=="GBK"
|
57
|
+
begin
|
58
|
+
return buffer.encode("UTF-8")
|
59
|
+
rescue Encoding::UndefinedConversionError=>e
|
60
|
+
if e.message.include?("from GBK to UTF-8")
|
61
|
+
buffer.force_encoding("UTF-8")
|
62
|
+
else
|
63
|
+
raise "#{e.message} (#{e.class})"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
return buffer
|
68
|
+
end
|
69
|
+
|
70
|
+
def save_into path
|
71
|
+
File.open(path,'w'){|f|f.write(self)}
|
72
|
+
end
|
73
|
+
|
74
|
+
def save_binary_into path
|
75
|
+
File.open(path,'wb'){|f|f.write(self)}
|
76
|
+
end
|
77
|
+
|
78
|
+
def append_into path
|
79
|
+
unless File.exist?(path)
|
80
|
+
save_into(path)
|
81
|
+
else
|
82
|
+
File.open(path,'a'){|f|f.write(self)}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class Hash
|
88
|
+
# {FolderTree} => ["PathString"List]
|
89
|
+
def paths
|
90
|
+
traces = []
|
91
|
+
self.each do|name,tag|
|
92
|
+
traces << [name]
|
93
|
+
end
|
94
|
+
self.each do|name,tag|
|
95
|
+
if tag.is_a?(Hash)
|
96
|
+
subs = tag.paths
|
97
|
+
new_traces = []
|
98
|
+
traces.each do |trace|
|
99
|
+
if trace[-1] == name
|
100
|
+
new_sub = []
|
101
|
+
subs.each{|vector|new_sub << trace + vector}
|
102
|
+
new_traces += new_sub
|
103
|
+
else
|
104
|
+
new_traces << trace
|
105
|
+
end
|
106
|
+
end
|
107
|
+
traces = new_traces
|
108
|
+
end
|
109
|
+
end
|
110
|
+
return traces
|
111
|
+
end
|
112
|
+
|
113
|
+
def find_path nodename
|
114
|
+
result = []
|
115
|
+
self.paths.each do|path|
|
116
|
+
result << path.join("/") if path.join("/").include?(nodename)
|
117
|
+
end
|
118
|
+
return result
|
119
|
+
end
|
120
|
+
|
121
|
+
alias :"find?" :find_path
|
122
|
+
end
|
123
|
+
|
124
|
+
load('json.rb') # require 'json'
|
125
|
+
load('yaml.rb') # require 'yaml'
|
126
|
+
|
127
|
+
class File
|
128
|
+
def self.load_json filepath
|
129
|
+
path = filepath.include?('.json') ? filepath : filepath+".json"
|
130
|
+
context = File.open(path,'r'){|f|f.read}.force_encoding("UTF-8")
|
131
|
+
JSON.parse(context)
|
132
|
+
end
|
133
|
+
|
134
|
+
# ...
|
135
|
+
# yaml = YAML.dump( obj )
|
136
|
+
# obj = YAML.load( yaml )
|
137
|
+
# File.open( 'path.yaml', 'w' ) do |out| YAML.dump( obj, out ) end
|
138
|
+
# obj = YAML.load_file("path.yaml")
|
139
|
+
def self.load_yaml filepath
|
140
|
+
path = filepath.include?('.yml') ? filepath : filepath+".yml"
|
141
|
+
context = File.open(path,'r'){|f|f.read}.force_encoding("UTF-8")
|
142
|
+
YAML.load(context)
|
143
|
+
end
|
144
|
+
|
145
|
+
# 这个方法保证对象中的unicode被正确转换为YAML内容(已过时)
|
146
|
+
# eg. File.open('temp.yml','w'){|f|f.write [ "alphabet",{:symbol=>123.321},'"其♂ 他·文♀字"' ].to_yaml.unicode}
|
147
|
+
# def unicode
|
148
|
+
# yaml_string = self#.to_yaml # only valid for yaml string!
|
149
|
+
# yml_unic = begin
|
150
|
+
# str = (/\"(.+)\"/.match yaml_string)[0]
|
151
|
+
# yaml_string.gsub(str,eval(":#{str}").to_s)
|
152
|
+
# rescue
|
153
|
+
# yaml_string
|
154
|
+
# end
|
155
|
+
# return yml_unic
|
156
|
+
# end
|
157
|
+
|
158
|
+
def self.clear_edit_backfile path
|
159
|
+
if File.exist?(path) && path[-1]=='~'
|
160
|
+
File.delete(path)
|
161
|
+
puts "Delete #{path} successfully!"
|
162
|
+
else
|
163
|
+
puts "Cannot delete #{path}, just pass away!"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.clear_edit_backfile_path path='.'
|
168
|
+
Dir["#{path}/*~"].each do|path|
|
169
|
+
begin
|
170
|
+
File.delete(path)
|
171
|
+
puts "Delete #{path} successfully!"
|
172
|
+
rescue
|
173
|
+
puts "Cannot delete #{path}, just pass away!"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def self.diff left_path, right_path, report_path='tmp.diff', selector='diff'
|
179
|
+
`echo "\n#{Array.new(64,'-').join}\n" >> #{report_path}`
|
180
|
+
`echo "<< #{left_path} <=> #{right_path} >>\n" >> #{report_path}`
|
181
|
+
`#{selector} #{left_path} #{right_path} >> #{report_path}`
|
182
|
+
end
|
183
|
+
|
184
|
+
def self.diffs adir, bdir, head='.',selector='diff'
|
185
|
+
alist = (head+'/'+adir).directory_detection.paths.map{|path|path.join('/')}
|
186
|
+
blist = (head+'/'+bdir).directory_detection.paths.map{|path|path.join('/')}
|
187
|
+
|
188
|
+
onlyalist = alist - blist
|
189
|
+
onlyblist = blist - alist
|
190
|
+
commnlist = alist & blist
|
191
|
+
|
192
|
+
report = []
|
193
|
+
unless onlyalist.empty?
|
194
|
+
report << "only #{adir} exist files:\n"
|
195
|
+
report += onlyalist.map{|path|path}
|
196
|
+
report << '' << Array.new(64,'=').join
|
197
|
+
end
|
198
|
+
|
199
|
+
unless onlyblist.empty?
|
200
|
+
report << "\nonly #{bdir} exist files:\n"
|
201
|
+
report += onlyblist.map{|path|path}
|
202
|
+
report << '' << Array.new(64,'=').join
|
203
|
+
end
|
204
|
+
|
205
|
+
unless commnlist.empty?
|
206
|
+
report << "\ncommon files comparison:"
|
207
|
+
commnlist.each do|path|
|
208
|
+
self.diff("#{head}/#{adir}/#{path}", "#{head}/#{bdir}/#{path}", 'diff.tmp', selector)
|
209
|
+
end
|
210
|
+
File.exist?('diff.tmp') and report << File.read('diff.tmp')
|
211
|
+
File.exist?('diff.tmp') and File.delete('diff.tmp')
|
212
|
+
end
|
213
|
+
|
214
|
+
return report.join("\n")
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
module Diff
|
219
|
+
module_function
|
220
|
+
|
221
|
+
# 该方法只用来排成两列显示, 并不真正执行比较, 已经有File.diff/File.diffs完成该工作
|
222
|
+
def show text1, text2, shift=0
|
223
|
+
list1 = text1.instance_of?(String) ? text1.split("\n") : text1
|
224
|
+
list2 = text2.instance_of?(String) ? text2.split("\n") : text2
|
225
|
+
max1 = list1.map{|r|r.length}.max
|
226
|
+
max2 = list2.map{|r|r.length}.max
|
227
|
+
shift > 0 and (list1 = Array.new(shift, "")+list1) #and (list2 += Array.new(shift, ""))
|
228
|
+
shift <= 0 and (list2 = Array.new(shift, "")+list2)# and (list1 += Array.new(shift, ""))
|
229
|
+
size = [list1.size, list2.size].max+(shift>0 ? shift : shift*(-1))
|
230
|
+
rows = []
|
231
|
+
size.times.each do|index|
|
232
|
+
rows << [
|
233
|
+
list1[index].to_s+Array.new(max1 - list1[index].to_s.length, " ").join,
|
234
|
+
list2[index].to_s+Array.new(max2 - list2[index].to_s.length, " ").join
|
235
|
+
]
|
236
|
+
end
|
237
|
+
return rows
|
238
|
+
end
|
239
|
+
|
240
|
+
def shift text, index, shift=1
|
241
|
+
list = text.instance_of?(String) ? text.split("\n") : text
|
242
|
+
shift.times.each do list.insert(index,"") end
|
243
|
+
return list.join("\n")
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
class Integer
|
248
|
+
# 数字计量单位
|
249
|
+
def line;return self;end
|
250
|
+
def lines;return self;end
|
251
|
+
def row;return self;end
|
252
|
+
def rows;return self;end
|
253
|
+
end
|
data/kernel.rb
ADDED
@@ -0,0 +1,227 @@
|
|
1
|
+
#coding:utf-8
|
2
|
+
|
3
|
+
############################################################################################################
|
4
|
+
# HOW TO USE #
|
5
|
+
############################################################################################################
|
6
|
+
|
7
|
+
=begin
|
8
|
+
require 'cc'
|
9
|
+
CC.use 'kernel' # immediately when loading this file
|
10
|
+
|
11
|
+
uses 'number', 'string'
|
12
|
+
reloads 'number','string'
|
13
|
+
|
14
|
+
module AModule
|
15
|
+
def a_method;'a';end
|
16
|
+
end
|
17
|
+
module BModule
|
18
|
+
def b_method;'b';end
|
19
|
+
end
|
20
|
+
class AClass
|
21
|
+
includes AModule, BModule
|
22
|
+
end
|
23
|
+
obj1 = AClass.new
|
24
|
+
p obj1.respond_to?(:a_method), obj1.respond_to?(:b_method)
|
25
|
+
|
26
|
+
obj2 = Object.new
|
27
|
+
p obj2.respond_to?(:a_method), obj2.respond_to?(:b_method)
|
28
|
+
obj2.extends AModule, BModule
|
29
|
+
p obj2.respond_to?(:a_method), obj2.respond_to?(:b_method)
|
30
|
+
|
31
|
+
class A1
|
32
|
+
def a2; A2.new; end
|
33
|
+
end
|
34
|
+
class A2
|
35
|
+
def a3; A3.new; end
|
36
|
+
end
|
37
|
+
class A3
|
38
|
+
def a4; A4.new; end
|
39
|
+
end
|
40
|
+
class A4
|
41
|
+
def a5; false; end
|
42
|
+
end
|
43
|
+
class String
|
44
|
+
def to_bill; return false; end
|
45
|
+
end
|
46
|
+
|
47
|
+
puts "a.sends(:b,:c,:d) => #{A1.new.sends(:a2,Proc.new{|i|i.send :a3},:a4)} #=> #<A4 ...>"
|
48
|
+
# a.sends(:b,:c,:d) => #<A4:0x0000000006425648> #=> #<A4 ...>
|
49
|
+
|
50
|
+
puts "a.cond_insect(:b,:c,:d) => #{A1.new.cond_insect(:a2,lambda{|s|s.send :a3},:a4 ) ? :true : :false}"
|
51
|
+
# a.cond_insect(:b,:c,:d) => true
|
52
|
+
|
53
|
+
puts "a.cond_union(:b,:c,:d) => #{A3.new.cond_union(:a4,Proc.new{|s|s.a5},:to_s,'to_bill' ) ? :true : :false} #=> #<A4 ...> "
|
54
|
+
# a.cond_union(:b,:c,:d) => true #=> #<A4 ...>
|
55
|
+
|
56
|
+
puts "a.mapr(fun1, fun2, fun3) => #{"15a".mapr(lambda{|s|s.to_i+1}, lambda{|s|s.to_s+"b"}, lambda{|s|s[-1]}).last}"
|
57
|
+
# a.mapr(fun1, fun2, fun3) => b
|
58
|
+
|
59
|
+
puts "a.check_insect(cond1, cond2, cond3) => #{"15a".check_insect( lambda{|s|s.to_i < 20}, lambda{|s|s.to_i > 10}, lambda{|s|s.size==3} )}"
|
60
|
+
# a.check_insect(cond1, cond2, cond3) => true
|
61
|
+
|
62
|
+
puts "a.check_union(cond1, cond2, cond3) => #{"15a".check_union( lambda{|s|s.is_a?(Symbol)}, lambda{|s|s.respond_to?(:to_json)}, lambda{|s|s.instance_of?(Module)} )}"
|
63
|
+
# a.check_union(cond1, cond2, cond3) => false
|
64
|
+
=end
|
65
|
+
|
66
|
+
module Kernel
|
67
|
+
def requires *script_names
|
68
|
+
script_names.each do|script_name|
|
69
|
+
use script_name#.encode('GBK')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def use script_path
|
74
|
+
if File.exist?(script_path)
|
75
|
+
require_relative script_path
|
76
|
+
elsif File.exist?(script_path+'.rb')
|
77
|
+
require_relative script_path+'.rb'
|
78
|
+
else
|
79
|
+
warn "无法找到路径: #{script_path}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
alias :uses :requires
|
84
|
+
|
85
|
+
def reloads *script_paths
|
86
|
+
script_paths.each do|script_path|
|
87
|
+
reload script_path
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def reload script_path
|
92
|
+
if File.exist?(script_path)
|
93
|
+
load script_path
|
94
|
+
elsif File.exist?(script_path+'.rb')
|
95
|
+
load script_path+'.rb'
|
96
|
+
else
|
97
|
+
warn "无法找到路径: #{script_path}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def includes *modules
|
102
|
+
modules.each do|mod|
|
103
|
+
include mod
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
class Object
|
109
|
+
def extends *modules
|
110
|
+
modules.each do|mod|
|
111
|
+
extend mod
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
#######################################################
|
116
|
+
# walkthrough function-chain
|
117
|
+
#######################################################
|
118
|
+
|
119
|
+
# CALL: obj.sends(func1, func2, func3, ...)
|
120
|
+
# RETN: obj.func1.func2.func3...
|
121
|
+
def sends *funcs
|
122
|
+
target = self
|
123
|
+
funcs.each do|func|
|
124
|
+
if func.is_a?(Symbol) or func.is_a?(String)
|
125
|
+
target = target.send(*func)
|
126
|
+
elsif func.is_a?(Array)
|
127
|
+
target = target.send(*func)
|
128
|
+
elsif func.instance_of?(Proc)
|
129
|
+
target = func.call(*target)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
return target
|
133
|
+
end
|
134
|
+
|
135
|
+
# CALL: obj.maps(func1, func2, func3, ...)
|
136
|
+
# REPR: ... func3.call( func2.call( func1.call(obj) ) )
|
137
|
+
# RETN: [stack1, stack2, stack3, ...]
|
138
|
+
def mapr *funcs
|
139
|
+
red, target = [], self
|
140
|
+
funcs.each do|func|
|
141
|
+
if func.is_a?(Symbol) or func.is_a?(String)
|
142
|
+
target = target.send(*func)
|
143
|
+
elsif func.is_a?(Array)
|
144
|
+
target = target.send(*func)
|
145
|
+
elsif func.instance_of?(Proc)
|
146
|
+
target = func.call(*target)
|
147
|
+
end
|
148
|
+
red << target
|
149
|
+
end
|
150
|
+
return red
|
151
|
+
end
|
152
|
+
|
153
|
+
# CALL: obj.cond_ins(attr1, attr2, attr3, ...)
|
154
|
+
# REPR: obj.attr1 && obj.attr1.attr2 && obj.attr1.attr2.attr3...
|
155
|
+
# RETN: obj.attr1...attrn/false (false must be specified literally)
|
156
|
+
def cond_insect *funcs
|
157
|
+
target = self
|
158
|
+
flag = funcs.inject(true) do|flag, func|
|
159
|
+
if func.is_a?(Symbol) or func.is_a?(String)
|
160
|
+
target = target.send(*func)
|
161
|
+
elsif func.is_a?(Array)
|
162
|
+
target = target.send(*func)
|
163
|
+
elsif func.instance_of?(Proc)
|
164
|
+
target = func.call(*target)
|
165
|
+
end
|
166
|
+
flag && target
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# CALL: obj.cond_union(attr1, attr2, attr3, ...)
|
171
|
+
# REPR: obj.attr1 || obj.attr1.attr2 || obj.attr1.attr2.attr3...
|
172
|
+
# RETN: obj.attrX (Y>X, when obj.attrY is false/not exist, obj.attrX is the first not false)
|
173
|
+
def cond_union *funcs
|
174
|
+
target = self
|
175
|
+
flag = funcs.inject(false) do|flag, func|
|
176
|
+
if func.is_a?(Symbol) or func.is_a?(String)
|
177
|
+
target = target.send(*func)
|
178
|
+
elsif func.is_a?(Array)
|
179
|
+
target = target.send(*func)
|
180
|
+
elsif func.instance_of?(Proc)
|
181
|
+
target = func.call(*target)
|
182
|
+
end
|
183
|
+
flag || target
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
#######################################################
|
188
|
+
# map-reverse function-chain
|
189
|
+
#
|
190
|
+
# Tips:
|
191
|
+
# map := obj.map{|o|func(o)}
|
192
|
+
# map-reverse := funcs.map{|func|func(obj)}
|
193
|
+
#######################################################
|
194
|
+
|
195
|
+
# CALL: obj.check_insect(cond1, cond2, cond3, ...)
|
196
|
+
# REPR: cond1(obj) && cond2(obj) && cond3(obj) ...
|
197
|
+
# RETN: blockn(obj)/false (false must be specified)
|
198
|
+
def check_insect *funcs
|
199
|
+
flag = funcs.inject(true) do|flag, func|
|
200
|
+
if func.is_a?(Symbol) or func.is_a?(String)
|
201
|
+
flag && self.send(func)
|
202
|
+
elsif func.is_a?(Array)
|
203
|
+
flag && self.send(*func)
|
204
|
+
else
|
205
|
+
flag && func.call(*self)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# CALL: obj.check_union(cond1, cond2, cond3, ...)
|
211
|
+
# REPR: cond1(obj) || cond2(obj) || cond3(obj) ...
|
212
|
+
# RETN: true/false
|
213
|
+
def check_union *funcs
|
214
|
+
flag = funcs.inject(false) do|flag, func|
|
215
|
+
if func.is_a?(Symbol) or func.is_a?(String)
|
216
|
+
flag || self.send(func)
|
217
|
+
elsif func.is_a?(Array)
|
218
|
+
flag || self.send(*func)
|
219
|
+
else
|
220
|
+
flag || func.call(*self)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|
226
|
+
|
227
|
+
|
data/monkey-patch.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
#coding:utf-8
|
2
|
+
|
3
|
+
############################################################################################################
|
4
|
+
# HOW TO USE #
|
5
|
+
############################################################################################################
|
6
|
+
|
7
|
+
=begin
|
8
|
+
require 'cc'
|
9
|
+
CC.use 'monkey-patch'
|
10
|
+
|
11
|
+
class A1
|
12
|
+
def a1; :a1; end
|
13
|
+
end
|
14
|
+
|
15
|
+
class A2 < A1
|
16
|
+
def a2; :a2; end
|
17
|
+
end
|
18
|
+
|
19
|
+
module Mod1
|
20
|
+
def mod1; :mod1; end
|
21
|
+
end
|
22
|
+
|
23
|
+
module Mod2
|
24
|
+
def mod2; :mod2; end
|
25
|
+
end
|
26
|
+
|
27
|
+
class A1
|
28
|
+
include Mod1
|
29
|
+
end
|
30
|
+
|
31
|
+
a = A2.new
|
32
|
+
a.extend Mod2
|
33
|
+
|
34
|
+
puts '',"一个实例的独有方法 = 它的基类实例方法 - 它的父类实例方法 = 本级实例方法 + 本实例扩展方法"
|
35
|
+
p a.unique_methods == a.compize(A1)
|
36
|
+
|
37
|
+
puts '',"一个实例的独有方法 根据它选择的基类不同而不同"
|
38
|
+
p a.compize(Object), a.compize(A1), a.compize(A2)
|
39
|
+
|
40
|
+
puts '',"但不基于模块方法"
|
41
|
+
p a.compize(Mod1), a.compize(Mod2)
|
42
|
+
|
43
|
+
puts '',"打标签备份方法"
|
44
|
+
p a.compize(Object), a.mod1, a.mod2
|
45
|
+
class << a
|
46
|
+
verize :mod1, "20110101"
|
47
|
+
revise :mod1, :mod2
|
48
|
+
def mod1; :mod3; end
|
49
|
+
end
|
50
|
+
p a.compize(Object), a.mod1, a.mod2, a.mod1_20110101
|
51
|
+
=end
|
52
|
+
|
53
|
+
class Object
|
54
|
+
attr_accessor :main_version, :versions
|
55
|
+
|
56
|
+
def versions
|
57
|
+
@versions ||= []
|
58
|
+
end
|
59
|
+
|
60
|
+
def versions= newver
|
61
|
+
@versions ||= []
|
62
|
+
@versions << newver unless @versions.include?(newver)
|
63
|
+
@main_version = newver
|
64
|
+
return newver
|
65
|
+
end
|
66
|
+
|
67
|
+
def revise method1,method2
|
68
|
+
alias_method "tempfunc1",method1
|
69
|
+
alias_method "tempfunc2",method2
|
70
|
+
alias_method method1, "tempfunc2"
|
71
|
+
alias_method method2, "tempfunc1"
|
72
|
+
end
|
73
|
+
|
74
|
+
def compize klass=nil
|
75
|
+
return self.methods - self.class.superclass.instance_methods if klass.nil?
|
76
|
+
return self.methods - klass.instance_methods
|
77
|
+
end
|
78
|
+
|
79
|
+
def verize name, tag=nil
|
80
|
+
tag = Time.new.strftime("%Y%m%d%H%M%S") unless tag
|
81
|
+
new_name, old_name = "#{name}_#{tag}",name
|
82
|
+
alias_method new_name, old_name
|
83
|
+
end
|
84
|
+
|
85
|
+
def verize_all tag=nil
|
86
|
+
tag = Time.new.strftime("%Y%m%d%H%M%S") unless tag
|
87
|
+
unique_methods.each do|um|
|
88
|
+
new_name, old_name = "#{um}_#{tag}", um
|
89
|
+
alias_method new_name, old_name
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def unique_methods
|
94
|
+
self.methods - self.class.superclass.instance_methods
|
95
|
+
end
|
96
|
+
|
97
|
+
def defm name, &block
|
98
|
+
@____ ||= Hash.new
|
99
|
+
@____[name] = block
|
100
|
+
end
|
101
|
+
|
102
|
+
def callm name, *args
|
103
|
+
@____[name].call(*args)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
module Kernel
|
108
|
+
def defp name, &block
|
109
|
+
@____ ||= Hash.new
|
110
|
+
@____[name] = block
|
111
|
+
end
|
112
|
+
|
113
|
+
def callp name, *args
|
114
|
+
@____[name].call(*args)
|
115
|
+
end
|
116
|
+
end
|
data/number.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
#coding:utf-8
|
2
|
+
|
3
|
+
############################################################################################################
|
4
|
+
# HOW TO USE #
|
5
|
+
############################################################################################################
|
6
|
+
|
7
|
+
=begin
|
8
|
+
require 'cc'
|
9
|
+
CC.use 'number' # immediately when loading this file
|
10
|
+
|
11
|
+
puts "Float to percentage:"
|
12
|
+
p 0.5.to_percentage, 0.55.to_percentage, 0.555.to_percentage, 0.5555.to_percentage
|
13
|
+
|
14
|
+
puts '',"Float to binary and hexadecimal:"
|
15
|
+
p 1102274184.317453.binform, 1102274184.317453.hexform
|
16
|
+
|
17
|
+
puts '',"Binary and Hexadecimal String to float:"
|
18
|
+
p "41b35e88.514498".as_hexnum, "1000001101100110101111010001000.010100010100010010011".as_binnum
|
19
|
+
|
20
|
+
puts '',"The Integral:"
|
21
|
+
include Math
|
22
|
+
def 积分函数(x,y);x-y;end
|
23
|
+
def f(x);x;end
|
24
|
+
p a = ∫(5,30,1000.0){|x|积分函数(x, 5)}
|
25
|
+
p b = 积分(5,30){|x|f(x)}
|
26
|
+
=end
|
27
|
+
|
28
|
+
class Float
|
29
|
+
def to_percentage tail=2
|
30
|
+
"#{(self*100).round(tail)}%"
|
31
|
+
end
|
32
|
+
|
33
|
+
def binform d=100
|
34
|
+
mant = self%1
|
35
|
+
unless mant==0
|
36
|
+
list,cnt = [],0
|
37
|
+
while cnt<d && mant%1!=0
|
38
|
+
result = (mant%1)*2
|
39
|
+
list << "%b"%result.to_i
|
40
|
+
mant = result%1
|
41
|
+
cnt += 1
|
42
|
+
end
|
43
|
+
return "%b"%(self.to_i)+'.'+list.join
|
44
|
+
else
|
45
|
+
return "%b"%self
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def hexform d=100
|
50
|
+
mant = self%1
|
51
|
+
unless mant==0
|
52
|
+
list,cnt = [],0
|
53
|
+
while cnt<d && mant%1!=0
|
54
|
+
result = (mant%1)*16
|
55
|
+
list << "%x"%result.to_i
|
56
|
+
mant = result%1
|
57
|
+
cnt += 1
|
58
|
+
end
|
59
|
+
return "%x"%(self.to_i)+'.'+list.join
|
60
|
+
else
|
61
|
+
return "%x"%self
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Integer
|
67
|
+
def to_percentage tail=2
|
68
|
+
"#{(self/100.0).round(tail)}%"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class String
|
73
|
+
def to_float
|
74
|
+
self.include?("%") ? self.split("%")[0].to_f/100 : self.to_f
|
75
|
+
end
|
76
|
+
|
77
|
+
def as_hexnum
|
78
|
+
int, float = self.split('.')
|
79
|
+
int10, float10 = eval("0x"+int), 0
|
80
|
+
float.split('').each_with_index{|f,i|float10 += eval("0x"+f)*16**(-1*(i+1))}
|
81
|
+
return (int10+float10).to_f
|
82
|
+
end
|
83
|
+
|
84
|
+
def as_binnum
|
85
|
+
int, float = self.split('.')
|
86
|
+
int2, float2 = eval("0b"+int), 0
|
87
|
+
float.split('').each_with_index{|f,i|float2 += eval("0b"+f)*2**(-1*(i+1))}
|
88
|
+
return (int2+float2).to_f
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
module Math
|
93
|
+
def ∫(下限,上限,等分数=1000)
|
94
|
+
sum, x, dx = 0, 下限, (上限-下限)/(等分数*1.0)
|
95
|
+
loop do
|
96
|
+
y = yield(x)
|
97
|
+
sum += dx * y
|
98
|
+
x += dx
|
99
|
+
break if x>上限
|
100
|
+
end
|
101
|
+
return sum
|
102
|
+
end
|
103
|
+
|
104
|
+
alias :积分 :∫
|
105
|
+
end
|