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.
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