source: EcnlProtoTool/trunk/mruby-1.2.0/mrblib/string.rb@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby
File size: 5.4 KB
RevLine 
[270]1##
2# String
3#
4# ISO 15.2.10
5class String
6 include Comparable
7 ##
8 # Calls the given block for each line
9 # and pass the respective line.
10 #
11 # ISO 15.2.10.5.15
12 def each_line(&block)
13 offset = 0
14 while pos = self.index("\n", offset)
15 block.call(self[offset, pos + 1 - offset])
16 offset = pos + 1
17 end
18 block.call(self[offset, self.size - offset]) if self.size > offset
19 self
20 end
21
22 # private method for gsub/sub
23 def __sub_replace(pre, m, post)
24 s = ""
25 i = 0
26 while j = index("\\", i)
27 break if j == length-1
28 t = case self[j+1]
29 when "\\"
30 "\\"
31 when "`"
32 pre
33 when "&", "0"
34 m
35 when "'"
36 post
37 else
38 self[j, 2]
39 end
40 s += self[i, j-i] + t
41 i = j + 2
42 end
43 s + self[i, length-i]
44 end
45
46 ##
47 # Replace all matches of +pattern+ with +replacement+.
48 # Call block (if given) for each match and replace
49 # +pattern+ with the value of the block. Return the
50 # final value.
51 #
52 # ISO 15.2.10.5.18
53 def gsub(*args, &block)
54 if args.size == 2
55 s = ""
56 i = 0
57 while j = index(args[0], i)
58 seplen = args[0].length
59 k = j + seplen
60 pre = self[0, j]
61 post = self[k, length-k]
62 s += self[i, j-i] + args[1].__sub_replace(pre, args[0], post)
63 i = k
64 end
65 s + self[i, length-i]
66 elsif args.size == 1 && block
67 split(args[0], -1).join(block.call(args[0]))
68 else
69 raise ArgumentError, "wrong number of arguments"
70 end
71 end
72
73 ##
74 # Replace all matches of +pattern+ with +replacement+.
75 # Call block (if given) for each match and replace
76 # +pattern+ with the value of the block. Modify
77 # +self+ with the final value.
78 #
79 # ISO 15.2.10.5.19
80 def gsub!(*args, &block)
81 str = self.gsub(*args, &block)
82 return nil if str == self
83 self.replace(str)
84 end
85
86 ##
87 # Calls the given block for each match of +pattern+
88 # If no block is given return an array with all
89 # matches of +pattern+.
90 #
91 # ISO 15.2.10.5.32
92 def scan(reg, &block)
93 ### *** TODO *** ###
94 unless Object.const_defined?(:Regexp)
95 raise NotImplementedError, "scan not available (yet)"
96 end
97 end
98
99 ##
100 # Replace only the first match of +pattern+ with
101 # +replacement+. Call block (if given) for each
102 # match and replace +pattern+ with the value of the
103 # block. Return the final value.
104 #
105 # ISO 15.2.10.5.36
106 def sub(*args, &block)
107 if args.size == 2
108 pre, post = split(args[0], 2)
109 return self unless post # The sub target wasn't found in the string
110 pre + args[1].__sub_replace(pre, args[0], post) + post
111 elsif args.size == 1 && block
112 split(args[0], 2).join(block.call(args[0]))
113 else
114 raise ArgumentError, "wrong number of arguments"
115 end
116 end
117
118 ##
119 # Replace only the first match of +pattern+ with
120 # +replacement+. Call block (if given) for each
121 # match and replace +pattern+ with the value of the
122 # block. Modify +self+ with the final value.
123 #
124 # ISO 15.2.10.5.37
125 def sub!(*args, &block)
126 str = self.sub(*args, &block)
127 return nil if str == self
128 self.replace(str)
129 end
130
131 ##
132 # Call the given block for each character of
133 # +self+.
134 def each_char(&block)
135 pos = 0
136 while pos < self.size
137 block.call(self[pos])
138 pos += 1
139 end
140 self
141 end
142
143 ##
144 # Call the given block for each byte of +self+.
145 def each_byte(&block)
146 bytes = self.bytes
147 pos = 0
148 while pos < bytes.size
149 block.call(bytes[pos])
150 pos += 1
151 end
152 self
153 end
154
155 ##
156 # Modify +self+ by replacing the content of +self+.
157 # The portion of the string affected is determined using the same criteria as +String#[]+.
158 def []=(*args)
159 anum = args.size
160 if anum == 2
161 pos, value = args
162 if pos.kind_of? String
163 posnum = self.index(pos)
164 if posnum
165 b = self[0, posnum.to_i]
166 a = self[(posnum + pos.length)..-1]
167 self.replace([b, value, a].join(''))
168 return value
169 else
170 raise IndexError, "string not matched"
171 end
172 else
173 pos += self.length if pos < 0
174 if pos < 0 || pos > self.length
175 raise IndexError, "index #{args[0]} out of string"
176 end
177 b = self[0, pos.to_i]
178 a = self[pos + 1..-1]
179 self.replace([b, value, a].join(''))
180 return value
181 end
182 elsif anum == 3
183 pos, len, value = args
184 pos += self.length if pos < 0
185 if pos < 0 || pos > self.length
186 raise IndexError, "index #{args[0]} out of string"
187 end
188 if len < 0
189 raise IndexError, "negative length #{len}"
190 end
191 b = self[0, pos.to_i]
192 a = self[pos + len..-1]
193 self.replace([b, value, a].join(''))
194 return value
195 else
196 raise ArgumentError, "wrong number of arguments (#{anum} for 2..3)"
197 end
198 end
199
200 ##
201 # ISO 15.2.10.5.3
202 def =~(re)
203 raise TypeError, "type mismatch: String given" if re.respond_to? :to_str
204 re =~ self
205 end
206
207 ##
208 # ISO 15.2.10.5.27
209 def match(re, &block)
210 if re.respond_to? :to_str
211 if Object.const_defined?(:Regexp)
212 r = Regexp.new(re)
213 r.match(self, &block)
214 else
215 raise NotImplementedError, "String#match needs Regexp class"
216 end
217 else
218 re.match(self, &block)
219 end
220 end
221end
222
223##
224# String is comparable
225#
226# ISO 15.2.10.3
227module Comparable; end
228class String
229 include Comparable
230end
Note: See TracBrowser for help on using the repository browser.