Class: Range
- Includes:
- Enumerable
- Defined in:
- mruby/mrblib/range.rb,
mruby/src/range.c,
mruby/mrbgems/mruby-range-ext/mrblib/range.rb
Overview
Range
ISO 15.2.14
Constant Summary
Constants included from Enumerable
Instance Method Summary collapse
-
#==(obj) ⇒ Boolean
Returns
true
only if 1) obj is a Range, 2) obj has equivalent beginning and end items (by comparing them with==
), 3) obj has the same #exclude_end? setting as <i>rng</t>. - #=== ⇒ Object
-
#__num_to_a ⇒ Object
15.2.14.4.15(x).
-
#begin ⇒ Object
Returns the first object in rng.
-
#each(&block) ⇒ Object
Calls the given block for each element of
self
and pass the respective element. -
#end ⇒ Object
Returns the object that defines the end of rng.
-
#eql?(obj) ⇒ Boolean
Returns
true
only if obj is a Range, has equivalent beginning and end items (by comparing them with #eql?), and has the same #exclude_end? setting as rng. -
#exclude_end? ⇒ Boolean
Returns
true
if range excludes its end value. -
#first(*args) ⇒ Object
call-seq: rng.first -> obj rng.first(n) -> an_array.
-
#hash ⇒ Object
redefine #hash 15.3.1.3.15.
- #include? ⇒ Object
-
#new(start, end) ⇒ Object
constructor
Constructs a range using the given start and end.
-
#initialize_copy ⇒ Object
15.2.14.4.15(x).
-
#inspect ⇒ String
Convert this range object to a printable form (using
inspect
to convert the start and end objects). -
#last(*args) ⇒ Object
call-seq: rng.last -> obj rng.last(n) -> an_array.
- #max(&block) ⇒ Object
- #member? ⇒ Object
- #min(&block) ⇒ Object
-
#to_a ⇒ Object
(also: #entries)
call-seq: rng.to_a -> array rng.entries -> array.
-
#to_s ⇒ String
Convert this range object to a printable form.
Methods included from Enumerable
__update_hash, #all?, #any?, #chain, #collect, #count, #cycle, #detect, #drop, #drop_while, #each_cons, #each_slice, #each_with_index, #each_with_object, #filter_map, #find_all, #find_index, #flat_map, #grep, #group_by, #inject, #lazy, #max_by, #min_by, #minmax, #minmax_by, #none?, #one?, #partition, #reject, #reverse_each, #sort, #sort_by, #sum, #take, #take_while, #tally, #to_h, #uniq, #zip
Constructor Details
#new(start, end) ⇒ Object
Constructs a range using the given start and end. If the third parameter is omitted or is false
, the range will include the end object; otherwise, it will be excluded.
160 161 162 163 164 165 166 167 168 169 170 |
# File 'mruby/src/range.c', line 160
static mrb_value
range_initialize(mrb_state *mrb, mrb_value range)
{
mrb_value beg, end;
mrb_bool exclusive = FALSE;
mrb_get_args(mrb, "oo|b", &beg, &end, &exclusive);
range_ptr_replace(mrb, mrb_range_raw_ptr(range), beg, end, exclusive);
mrb_obj_freeze(mrb, range);
return range;
}
|
Instance Method Details
#==(obj) ⇒ Boolean
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'mruby/src/range.c', line 185
static mrb_value
range_eq(mrb_state *mrb, mrb_value range)
{
struct RRange *rr;
struct RRange *ro;
mrb_value obj = mrb_get_arg1(mrb);
mrb_bool v1, v2;
if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range))) { /* same class? */
return mrb_false_value();
}
rr = mrb_range_ptr(mrb, range);
ro = mrb_range_ptr(mrb, obj);
v1 = mrb_equal(mrb, RANGE_BEG(rr), RANGE_BEG(ro));
v2 = mrb_equal(mrb, RANGE_END(rr), RANGE_END(ro));
if (!v1 || !v2 || RANGE_EXCL(rr) != RANGE_EXCL(ro)) {
return mrb_false_value();
}
return mrb_true_value();
}
|
#===(obj) ⇒ Boolean #member?(val) ⇒ Boolean #include?(val) ⇒ Boolean
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'mruby/src/range.c', line 214
static mrb_value
range_include(mrb_state *mrb, mrb_value range)
{
mrb_value val = mrb_get_arg1(mrb);
struct RRange *r = mrb_range_ptr(mrb, range);
mrb_value beg, end;
beg = RANGE_BEG(r);
end = RANGE_END(r);
if (mrb_nil_p(beg)) {
if (RANGE_EXCL(r) ? r_gt(mrb, end, val) /* end > val */
: r_ge(mrb, end, val)) { /* end >= val */
return mrb_true_value();
}
}
else if (r_le(mrb, beg, val)) { /* beg <= val */
if (mrb_nil_p(end)) {
return mrb_true_value();
}
if (RANGE_EXCL(r) ? r_gt(mrb, end, val) /* end > val */
: r_ge(mrb, end, val)) { /* end >= val */
return mrb_true_value();
}
}
return mrb_false_value();
}
|
#__num_to_a ⇒ Object
15.2.14.4.15(x)
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 |
# File 'mruby/src/range.c', line 346
static mrb_value
range_num_to_a(mrb_state *mrb, mrb_value range)
{
struct RRange *r = mrb_range_ptr(mrb, range);
mrb_value beg = RANGE_BEG(r);
mrb_value end = RANGE_END(r);
mrb_value ary;
mrb->c->ci->mid = 0;
if (mrb_nil_p(end)) {
mrb_raise(mrb, E_RANGE_ERROR, "cannot convert endless range to an array");
}
if (mrb_integer_p(beg)) {
if (mrb_integer_p(end)) {
mrb_int a = mrb_integer(beg);
mrb_int b = mrb_integer(end);
mrb_int len;
if (mrb_int_sub_overflow(b, a, &len)) {
too_long:
mrb_raise(mrb, E_RANGE_ERROR, "integer range too long");
}
if (!RANGE_EXCL(r)) {
if (len == MRB_INT_MAX) goto too_long;
len++;
}
ary = mrb_ary_new_capa(mrb, len);
for (mrb_int i=0; i<len; i++) {
mrb_ary_push(mrb, ary, mrb_int_value(mrb, a+i));
}
return ary;
}
#ifndef MRB_NO_FLOAT
if (mrb_float_p(end)) {
mrb_float a = (mrb_float)mrb_integer(beg);
mrb_float b = mrb_float(end);
ary = mrb_ary_new_capa(mrb, (mrb_int)(b - a) + 1);
if (RANGE_EXCL(r)) {
while (a < b) {
mrb_ary_push(mrb, ary, mrb_int_value(mrb, (mrb_int)a));
a += 1.0;
}
}
else {
while (a <= b) {
mrb_ary_push(mrb, ary, mrb_int_value(mrb, (mrb_int)a));
a += 1.0;
}
}
return ary;
}
#endif
}
return mrb_nil_value();
}
|
#first ⇒ Object #begin ⇒ Object
Returns the first object in rng.
118 119 120 121 122 |
# File 'mruby/src/range.c', line 118
static mrb_value
range_beg(mrb_state *mrb, mrb_value range)
{
return mrb_range_beg(mrb, range);
}
|
#each(&block) ⇒ Object
Calls the given block for each element of self
and pass the respective element.
ISO 15.2.14.4.4
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'mruby/mrblib/range.rb', line 17 def each(&block) return to_enum :each unless block val = self.begin last = self.end if val.kind_of?(Integer) && last.nil? i = val while true block.call(i) i += 1 end return self end if val.kind_of?(String) && last.nil? if val.respond_to? :__upto_endless return val.__upto_endless(&block) else str_each = true end end if val.kind_of?(Integer) && last.kind_of?(Integer) # integers are special lim = last lim += 1 unless exclude_end? i = val while i < lim block.call(i) i += 1 end return self end if val.kind_of?(String) && last.kind_of?(String) # strings are special if val.respond_to? :upto return val.upto(last, exclude_end?, &block) else str_each = true end end raise TypeError, "can't iterate" unless val.respond_to? :succ return self if (val <=> last) > 0 while (val <=> last) < 0 block.call(val) val = val.succ if str_each break if val.size > last.size end end block.call(val) if !exclude_end? && (val <=> last) == 0 self end |
#end ⇒ Object #last ⇒ Object
Returns the object that defines the end of rng.
(1..10).end #=> 10
(1...10).end #=> 10
134 135 136 137 138 |
# File 'mruby/src/range.c', line 134
static mrb_value
range_end(mrb_state *mrb, mrb_value range)
{
return mrb_range_end(mrb, range);
}
|
#eql?(obj) ⇒ Boolean
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'mruby/src/range.c', line 307
static mrb_value
range_eql(mrb_state *mrb, mrb_value range)
{
mrb_value obj = mrb_get_arg1(mrb);
struct RRange *r, *o;
if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
if (!mrb_obj_is_kind_of(mrb, obj, mrb->range_class)) return mrb_false_value();
if (!mrb_range_p(obj)) return mrb_false_value();
r = mrb_range_ptr(mrb, range);
o = mrb_range_ptr(mrb, obj);
if (!mrb_eql(mrb, RANGE_BEG(r), RANGE_BEG(o)) ||
!mrb_eql(mrb, RANGE_END(r), RANGE_END(o)) ||
(RANGE_EXCL(r) != RANGE_EXCL(o))) {
return mrb_false_value();
}
return mrb_true_value();
}
|
#exclude_end? ⇒ Boolean
Returns true
if range excludes its end value.
146 147 148 149 150 |
# File 'mruby/src/range.c', line 146
static mrb_value
range_excl(mrb_state *mrb, mrb_value range)
{
return mrb_bool_value(mrb_range_excl_p(mrb, range));
}
|
#first(*args) ⇒ Object
call-seq:
rng.first -> obj
rng.first(n) -> an_array
Returns the first object in the range, or an array of the first n
elements.
(10..20).first #=> 10
(10..20).first(3) #=> [10, 11, 12]
118 119 120 121 122 |
# File 'mruby/src/range.c', line 118
static mrb_value
range_beg(mrb_state *mrb, mrb_value range)
{
return mrb_range_beg(mrb, range);
}
|
#hash ⇒ Object
redefine #hash 15.3.1.3.15
76 77 78 79 80 |
# File 'mruby/mrblib/range.rb', line 76 def hash h = first.hash ^ last.hash h += 1 if self.exclude_end? h end |
#===(obj) ⇒ Boolean #member?(val) ⇒ Boolean #include?(val) ⇒ Boolean
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'mruby/src/range.c', line 214
static mrb_value
range_include(mrb_state *mrb, mrb_value range)
{
mrb_value val = mrb_get_arg1(mrb);
struct RRange *r = mrb_range_ptr(mrb, range);
mrb_value beg, end;
beg = RANGE_BEG(r);
end = RANGE_END(r);
if (mrb_nil_p(beg)) {
if (RANGE_EXCL(r) ? r_gt(mrb, end, val) /* end > val */
: r_ge(mrb, end, val)) { /* end >= val */
return mrb_true_value();
}
}
else if (r_le(mrb, beg, val)) { /* beg <= val */
if (mrb_nil_p(end)) {
return mrb_true_value();
}
if (RANGE_EXCL(r) ? r_gt(mrb, end, val) /* end > val */
: r_ge(mrb, end, val)) { /* end >= val */
return mrb_true_value();
}
}
return mrb_false_value();
}
|
#initialize_copy ⇒ Object
15.2.14.4.15(x)
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'mruby/src/range.c', line 328
static mrb_value
range_initialize_copy(mrb_state *mrb, mrb_value copy)
{
mrb_value src = mrb_get_arg1(mrb);
struct RRange *r;
if (mrb_obj_equal(mrb, copy, src)) return copy;
if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) {
mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
}
r = mrb_range_ptr(mrb, src);
range_ptr_replace(mrb, mrb_range_raw_ptr(copy), RANGE_BEG(r), RANGE_END(r), RANGE_EXCL(r));
mrb_obj_freeze(mrb, copy);
return copy;
}
|
#inspect ⇒ String
Convert this range object to a printable form (using inspect
to convert the start and end objects).
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'mruby/src/range.c', line 272
static mrb_value
range_inspect(mrb_state *mrb, mrb_value range)
{
mrb_value str;
struct RRange *r = mrb_range_ptr(mrb, range);
if (!mrb_nil_p(RANGE_BEG(r))) {
str = mrb_inspect(mrb, RANGE_BEG(r));
str = mrb_str_dup(mrb, str);
mrb_str_cat(mrb, str, "...", RANGE_EXCL(r) ? 3 : 2);
}
else {
str = mrb_str_new(mrb, "...", RANGE_EXCL(r) ? 3 : 2);
}
if (!mrb_nil_p(RANGE_END(r))) {
mrb_value str2 = mrb_inspect(mrb, RANGE_END(r));
mrb_str_cat_str(mrb, str, str2);
}
return str;
}
|
#last(*args) ⇒ Object
call-seq:
rng.last -> obj
rng.last(n) -> an_array
Returns the last object in the range, or an array of the last n
elements.
Note that with no arguments last
will return the object that defines the end of the range even if #exclude_end? is true
.
(10..20).last #=> 20
(10...20).last #=> 20
(10..20).last(3) #=> [18, 19, 20]
(10...20).last(3) #=> [17, 18, 19]
134 135 136 137 138 |
# File 'mruby/src/range.c', line 134
static mrb_value
range_end(mrb_state *mrb, mrb_value range)
{
return mrb_range_end(mrb, range);
}
|
#max(&block) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'mruby/mrbgems/mruby-range-ext/mrblib/range.rb', line 56 def max(&block) val = self.begin last = self.end return super(&block) if block raise RangeError, "cannot get the maximum of endless range" if last.nil? # fast path for numerics if val.kind_of?(Numeric) && last.kind_of?(Numeric) raise TypeError if exclude_end? && !last.kind_of?(Integer) return nil if val > last return nil if val == last && exclude_end? max = last max -= 1 if exclude_end? return max end # delegate to Enumerable super() end |
#===(obj) ⇒ Boolean #member?(val) ⇒ Boolean #include?(val) ⇒ Boolean
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'mruby/src/range.c', line 214
static mrb_value
range_include(mrb_state *mrb, mrb_value range)
{
mrb_value val = mrb_get_arg1(mrb);
struct RRange *r = mrb_range_ptr(mrb, range);
mrb_value beg, end;
beg = RANGE_BEG(r);
end = RANGE_END(r);
if (mrb_nil_p(beg)) {
if (RANGE_EXCL(r) ? r_gt(mrb, end, val) /* end > val */
: r_ge(mrb, end, val)) { /* end >= val */
return mrb_true_value();
}
}
else if (r_le(mrb, beg, val)) { /* beg <= val */
if (mrb_nil_p(end)) {
return mrb_true_value();
}
if (RANGE_EXCL(r) ? r_gt(mrb, end, val) /* end > val */
: r_ge(mrb, end, val)) { /* end >= val */
return mrb_true_value();
}
}
return mrb_false_value();
}
|
#min(&block) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'mruby/mrbgems/mruby-range-ext/mrblib/range.rb', line 78 def min(&block) val = self.begin last = self.end if block raise RangeError, "cannot get the minimum of endless range with custom comparison method" if last.nil? return super(&block) end return val if last.nil? # fast path for numerics if val.kind_of?(Numeric) && last.kind_of?(Numeric) return nil if val > last return nil if val == last && exclude_end? min = val return min end # delegate to Enumerable super() end |
#to_a ⇒ Object Also known as: entries
call-seq:
rng.to_a -> array
rng.entries -> array
Returns an array containing the items in the range.
(1..7).to_a #=> [1, 2, 3, 4, 5, 6, 7]
(1..).to_a #=> RangeError: cannot convert endless range to an array
91 92 93 94 95 |
# File 'mruby/mrblib/range.rb', line 91 def to_a a = __num_to_a return a if a super end |
#to_s ⇒ String
Convert this range object to a printable form.
248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
# File 'mruby/src/range.c', line 248
static mrb_value
range_to_s(mrb_state *mrb, mrb_value range)
{
mrb_value str, str2;
struct RRange *r = mrb_range_ptr(mrb, range);
str = mrb_obj_as_string(mrb, RANGE_BEG(r));
str2 = mrb_obj_as_string(mrb, RANGE_END(r));
str = mrb_str_dup(mrb, str);
mrb_str_cat(mrb, str, "...", RANGE_EXCL(r) ? 3 : 2);
mrb_str_cat_str(mrb, str, str2);
return str;
}
|