非常教程

Ruby 2.4参考手册

范围 | Range

Range

父类:ObjectIncluded模块:Enumerable

A Range表示间隔 - 一组具有开始和结束的值。范围可以使用被构造小号..Ë小号...ë文字,或与新::。使用..从头到尾包含运行的构建范围。使用创建的那些...排除最终值。当用作迭代器时,范围返回序列中的每个值。

(-1..-5).to_a      #=> []
(-5..-1).to_a      #=> [-5, -4, -3, -2, -1]
('a'..'e').to_a    #=> ["a", "b", "c", "d", "e"]
('a'...'e').to_a   #=> ["a", "b", "c", "d"]

范围中的自定义对象

范围可以使用任何可以使用<=>操作符进行比较的对象来构造。将范围视为序列的方法(#each和从Enumerable继承的方法)期望begin对象实现一个succ方法来按顺序返回下一个对象。该步骤包括?方法需要begin对象来实现succ或是数字。

Xs以下两个类<=>succ被实现,以便Xs可以用于构建范围。请注意,包含了可比较模块,因此该==方法按照定义<=>

class Xs                # represent a string of 'x's
  include Comparable
  attr :length
  def initialize(n)
    @length = n
  end
  def succ
    Xs.new(@length + 1)
  end
  def <=>(other)
    @length <=> other.length
  end
  def to_s
    sprintf "%2d #{inspect}", @length
  end
  def inspect
    'x' * @length
  end
end

使用Xs构建范围的示例:

r = Xs.new(3)..Xs.new(6)   #=> xxx..xxxxxx
r.to_a                     #=> [xxx, xxxx, xxxxx, xxxxxx]
r.member?(Xs.new(5))       #=> true

公共类方法

json_create(object) Show source

通过构建带有a序列化参数的新Range对象来反序列化JSON字符串to_json

# File ext/json/lib/json/add/range.rb, line 10
def self.json_create(object)
  new(*object['a'])
end

new(begin, end, exclude_end=false) → rng Show source

使用给定的begin和构造一个范围end。如果exclude_end参数被省略或者是false,那么rng将包括结束对象; 否则,它将被排除。

static VALUE
range_initialize(int argc, VALUE *argv, VALUE range)
{
    VALUE beg, end, flags;

    rb_scan_args(argc, argv, "21", &beg, &end, &flags);
    range_modify(range);
    range_init(range, beg, end, RBOOL(RTEST(flags)));
    return Qnil;
}

公共实例方法

rng == obj → true or false Show source

true仅当obj是范围时才返回,具有相同的开始和结束项目(通过比较它们==),并且具有相同的exclude_end?设置为范围。

(0..2) == (0..2)            #=> true
(0..2) == Range.new(0,2)    #=> true
(0..2) == (0...2)           #=> false
static VALUE
range_eq(VALUE range, VALUE obj)
{
    if (range == obj)
        return Qtrue;
    if (!rb_obj_is_kind_of(obj, rb_cRange))
        return Qfalse;

    return rb_exec_recursive_paired(recursive_equal, range, obj, obj);
}

rng === obj → true or false Show source

true如果obj是范围的元素则返回,false否则返回。方便的===是,case报表使用的是比较运算符。

case 79
when 1..50   then   print "low\n"
when 51..75  then   print "medium\n"
when 76..100 then   print "high\n"
end

生产:

high
static VALUE
range_eqq(VALUE range, VALUE val)
{
    return rb_funcall(range, rb_intern("include?"), 1, val);
}

as_json(*) Show source

返回一个散列,它将变成一个JSON对象并表示这个对象。

# File ext/json/lib/json/add/range.rb, line 16
def as_json(*)
  {
    JSON.create_id  => self.class.name,
    'a'             => [ first, last, exclude_end? ]
  }
end

begin → obj Show source

返回定义范围起点的对象。

(1..10).begin   #=> 1
static VALUE
range_begin(VALUE range)
{
    return RANGE_BEG(range);
}

bsearch {|obj| block } → value Show source

通过使用二分查找,找到满足O(log n)中给定条件的范围内的值,其中n是该范围的大小。

您可以在两种使用情况下使用此方法:查找最小模式和查找任何模式。在任何一种情况下,范围的元素都必须是单调的(或排序)。

在find-minimum模式下(这对于典型用例来说是个不错的选择),块必须返回true或false,并且必须有一个值x,以便:

  • 对于任何小于x的值,块返回false
  • 对于任何大于或等于x的值,块返回true。

如果x在范围内,则此方法返回值x。否则,它返回nil。

ary = [0, 4, 7, 10, 12]
(0...ary.size).bsearch {|i| ary[i] >= 4 } #=> 1
(0...ary.size).bsearch {|i| ary[i] >= 6 } #=> 2
(0...ary.size).bsearch {|i| ary[i] >= 8 } #=> 3
(0...ary.size).bsearch {|i| ary[i] >= 100 } #=> nil

(0.0...Float::INFINITY).bsearch {|x| Math.log(x) >= 0 } #=> 1.0

在find-any模式下(这与libc的bsearch(3)相似),块必须返回一个数字,并且必须有两个值x和y(x <= y),以便:

  • 如果v <x,则块返回v的正数,
  • 如果x <= v <y,则块返回v
  • 如果y <= v,则块返回v的负数。

此方法返回给定范围和x ... y(如果有)的交集内的任何值。如果没有满足条件的值,则返回nil。

ary = [0, 100, 100, 100, 200]
(0..4).bsearch {|i| 100 - ary[i] } #=> 1, 2 or 3
(0..4).bsearch {|i| 300 - ary[i] } #=> nil
(0..4).bsearch {|i|  50 - ary[i] } #=> nil

你不能一次混合两种模式; 该块必须始终返回true / false,或始终返回一个数字。它没有定义在每次迭代中实际选取哪个值。

static VALUE
range_bsearch(VALUE range)
{
    VALUE beg, end, satisfied = Qnil;
    int smaller;

    /* Implementation notes:
     * Floats are handled by mapping them to 64 bits integers.
     * Apart from sign issues, floats and their 64 bits integer have the
     * same order, assuming they are represented as exponent followed
     * by the mantissa. This is true with or without implicit bit.
     *
     * Finding the average of two ints needs to be careful about
     * potential overflow (since float to long can use 64 bits)
     * as well as the fact that -1/2 can be 0 or -1 in C89.
     *
     * Note that -0.0 is mapped to the same int as 0.0 as we don't want
     * (-1...0.0).bsearch to yield -0.0.
     */

#define BSEARCH_CHECK(expr) \
    do { \
        VALUE val = (expr); \
        VALUE v = rb_yield(val); \
        if (FIXNUM_P(v)) { \
            if (v == INT2FIX(0)) return val; \
            smaller = (SIGNED_VALUE)v < 0; \
        } \
        else if (v == Qtrue) { \
            satisfied = val; \
            smaller = 1; \
        } \
        else if (v == Qfalse || v == Qnil) { \
            smaller = 0; \
        } \
        else if (rb_obj_is_kind_of(v, rb_cNumeric)) { \
            int cmp = rb_cmpint(rb_funcall(v, id_cmp, 1, INT2FIX(0)), v, INT2FIX(0)); \
            if (!cmp) return val; \
            smaller = cmp < 0; \
        } \
        else { \
            rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE \
                     " (must be numeric, true, false or nil)", \
                     rb_obj_class(v)); \
        } \
    } while (0)

#define BSEARCH(conv) \
    do { \
        RETURN_ENUMERATOR(range, 0, 0); \
        if (EXCL(range)) high--; \
        org_high = high; \
        while (low < high) { \
            mid = ((high < 0) == (low < 0)) ? low + ((high - low) / 2) \
                : (low < -high) ? -((-1 - low - high)/2 + 1) : (low + high) / 2; \
            BSEARCH_CHECK(conv(mid)); \
            if (smaller) { \
                high = mid; \
            } \
            else { \
                low = mid + 1; \
            } \
        } \
        if (low == org_high) { \
            BSEARCH_CHECK(conv(low)); \
            if (!smaller) return Qnil; \
        } \
        return satisfied; \
    } while (0)


    beg = RANGE_BEG(range);
    end = RANGE_END(range);

    if (FIXNUM_P(beg) && FIXNUM_P(end)) {
        long low = FIX2LONG(beg);
        long high = FIX2LONG(end);
        long mid, org_high;
        BSEARCH(INT2FIX);
    }
#if SIZEOF_DOUBLE == 8 && defined(HAVE_INT64_T)
    else if (RB_TYPE_P(beg, T_FLOAT) || RB_TYPE_P(end, T_FLOAT)) {
        int64_t low  = double_as_int64(RFLOAT_VALUE(rb_Float(beg)));
        int64_t high = double_as_int64(RFLOAT_VALUE(rb_Float(end)));
        int64_t mid, org_high;
        BSEARCH(int64_as_double_to_num);
    }
#endif
    else if (is_integer_p(beg) && is_integer_p(end)) {
        VALUE low = rb_to_int(beg);
        VALUE high = rb_to_int(end);
        VALUE mid, org_high;
        RETURN_ENUMERATOR(range, 0, 0);
        if (EXCL(range)) high = rb_funcall(high, '-', 1, INT2FIX(1));
        org_high = high;

        while (rb_cmpint(rb_funcall(low, id_cmp, 1, high), low, high) < 0) {
            mid = rb_funcall(rb_funcall(high, '+', 1, low), id_div, 1, INT2FIX(2));
            BSEARCH_CHECK(mid);
            if (smaller) {
                high = mid;
            }
            else {
                low = rb_funcall(mid, '+', 1, INT2FIX(1));
            }
        }
        if (rb_equal(low, org_high)) {
            BSEARCH_CHECK(low);
            if (!smaller) return Qnil;
        }
        return satisfied;
    }
    else {
        rb_raise(rb_eTypeError, "can't do binary search for %s", rb_obj_classname(beg));
    }
    return range;
}

cover?(obj) → true or false Show source

true如果obj在范围的开始和结束之间返回。

begin <= obj <= end在exclude_end时测试?是falsebegin <= obj < end当exclude_end?是true

("a".."z").cover?("c")    #=> true
("a".."z").cover?("5")    #=> false
("a".."z").cover?("cc")   #=> true
static VALUE
range_cover(VALUE range, VALUE val)
{
    VALUE beg, end;

    beg = RANGE_BEG(range);
    end = RANGE_END(range);
    return r_cover_p(range, beg, end, val);
}

each {| i | block } → rng Show source

each → an_enumerator

迭代范围元素,将每个元素依次传递给块。

each方法只能在范围的开始对象支持该succ方法时使用。如果对象没有succ定义方法(如Float),则会引发TypeError 。

如果没有给出块,则返回一个枚举器。

(10..15).each {|n| print n, ' ' }
# prints: 10 11 12 13 14 15

(2.5..5).each {|n| print n, ' ' }
# raises: TypeError: can't iterate from Float
static VALUE
range_each(VALUE range)
{
    VALUE beg, end;

    RETURN_SIZED_ENUMERATOR(range, 0, 0, range_enum_size);

    beg = RANGE_BEG(range);
    end = RANGE_END(range);

    if (FIXNUM_P(beg) && FIXNUM_P(end)) { /* fixnums are special */
        long lim = FIX2LONG(end);
        long i;

        if (!EXCL(range))
            lim += 1;
        for (i = FIX2LONG(beg); i < lim; i++) {
            rb_yield(LONG2FIX(i));
        }
    }
    else if (SYMBOL_P(beg) && SYMBOL_P(end)) { /* symbols are special */
        VALUE args[2];

        args[0] = rb_sym2str(end);
        args[1] = EXCL(range) ? Qtrue : Qfalse;
        rb_block_call(rb_sym2str(beg), rb_intern("upto"), 2, args, sym_each_i, 0);
    }
    else {
        VALUE tmp = rb_check_string_type(beg);

        if (!NIL_P(tmp)) {
            VALUE args[2];

            args[0] = end;
            args[1] = EXCL(range) ? Qtrue : Qfalse;
            rb_block_call(tmp, rb_intern("upto"), 2, args, each_i, 0);
        }
        else {
            if (!discrete_object_p(beg)) {
                rb_raise(rb_eTypeError, "can't iterate from %s",
                         rb_obj_classname(beg));
            }
            range_each_func(range, each_i, 0);
        }
    }
    return range;
}

end → obj Show source

返回定义范围结束的对象。

(1..10).end    #=> 10
(1...10).end   #=> 10
static VALUE
range_end(VALUE range)
{
    return RANGE_END(range);
}

eql?(obj) → true or false Show source

true仅当obj是范围时才返回,具有相同的开始和结束项目(通过比较它们eql?),并且具有相同的exclude_end?设置为范围。

(0..2).eql?(0..2)            #=> true
(0..2).eql?(Range.new(0,2))  #=> true
(0..2).eql?(0...2)           #=> false
static VALUE
range_eql(VALUE range, VALUE obj)
{
    if (range == obj)
        return Qtrue;
    if (!rb_obj_is_kind_of(obj, rb_cRange))
        return Qfalse;
    return rb_exec_recursive_paired(recursive_eql, range, obj, obj);
}

exclude_end? → true or false Show source

true如果范围排除其最终值,则返回。

(1..5).exclude_end?     #=> false
(1...5).exclude_end?    #=> true
static VALUE
range_exclude_end_p(VALUE range)
{
    return EXCL(range) ? Qtrue : Qfalse;
}

first → obj Show source

first(n) → an_array

返回范围中的第一个对象或第一个n元素的数组。

(10..20).first     #=> 10
(10..20).first(3)  #=> [10, 11, 12]
static VALUE
range_first(int argc, VALUE *argv, VALUE range)
{
    VALUE n, ary[2];

    if (argc == 0) return RANGE_BEG(range);

    rb_scan_args(argc, argv, "1", &n);
    ary[0] = n;
    ary[1] = rb_ary_new2(NUM2LONG(n));
    rb_block_call(range, idEach, 0, 0, first_i, (VALUE)ary);

    return ary[1];
}

hash → integer Show source

计算此范围的散列码。两个范围具有相同的开始点和结束点(使用eql?),以及相同的exclude_end?值将生成相同的散列码。

See also Object#hash.

static VALUE
range_hash(VALUE range)
{
    st_index_t hash = EXCL(range);
    VALUE v;

    hash = rb_hash_start(hash);
    v = rb_hash(RANGE_BEG(range));
    hash = rb_hash_uint(hash, NUM2LONG(v));
    v = rb_hash(RANGE_END(range));
    hash = rb_hash_uint(hash, NUM2LONG(v));
    hash = rb_hash_uint(hash, EXCL(range) << 24);
    hash = rb_hash_end(hash);

    return LONG2FIX(hash);
}

include?(obj) → true or false Show source

true如果obj是范围的元素则返回,false否则返回。如果开始和结束是数字,则根据值的大小进行比较。

("a".."z").include?("g")   #=> true
("a".."z").include?("A")   #=> false
("a".."z").include?("cc")  #=> false
static VALUE
range_include(VALUE range, VALUE val)
{
    VALUE beg = RANGE_BEG(range);
    VALUE end = RANGE_END(range);
    int nv = FIXNUM_P(beg) || FIXNUM_P(end) ||
             linear_object_p(beg) || linear_object_p(end);

    if (nv ||
        !NIL_P(rb_check_to_integer(beg, "to_int")) ||
        !NIL_P(rb_check_to_integer(end, "to_int"))) {
        return r_cover_p(range, beg, end, val);
    }
    else if (RB_TYPE_P(beg, T_STRING) && RB_TYPE_P(end, T_STRING)) {
        VALUE rb_str_include_range_p(VALUE beg, VALUE end, VALUE val, VALUE exclusive);
        return rb_str_include_range_p(beg, end, val, RANGE_EXCL(range));
    }
    /* TODO: ruby_frame->this_func = rb_intern("include?"); */
    return rb_call_super(1, &val);
}

inspect → string Show source

将此范围对象转换为可打印格式(inspect用于转换开始和结束对象)。

static VALUE
range_inspect(VALUE range)
{
    return rb_exec_recursive(inspect_range, range, 0);
}

last → obj Show source

last(n) → an_array

返回范围中的最后一个对象或最后一个n元素的数组。

请注意,没有参数last会返回定义范围结尾的对象,即使是exclude_end?是true

(10..20).last      #=> 20
(10...20).last     #=> 20
(10..20).last(3)   #=> [18, 19, 20]
(10...20).last(3)  #=> [17, 18, 19]
static VALUE
range_last(int argc, VALUE *argv, VALUE range)
{
    if (argc == 0) return RANGE_END(range);
    return rb_ary_last(argc, argv, rb_Array(range));
}

max → obj Show source

max {| a,b | block } → obj

max(n) → obj

max(n) {| a,b | block } → obj

返回范围中的最大值。返回nil,如果开始比端值大的范围内的值。返回nil如果独占范围的开始值等于终值。

可以给定一个可选块来覆盖默认的比较方法a <=> b

(10..20).max    #=> 20
static VALUE
range_max(int argc, VALUE *argv, VALUE range)
{
    VALUE e = RANGE_END(range);
    int nm = FIXNUM_P(e) || rb_obj_is_kind_of(e, rb_cNumeric);

    if (rb_block_given_p() || (EXCL(range) && !nm) || argc) {
        return rb_call_super(argc, argv);
    }
    else {
        VALUE b = RANGE_BEG(range);
        int c = rb_cmpint(rb_funcall(b, id_cmp, 1, e), b, e);

        if (c > 0)
            return Qnil;
        if (EXCL(range)) {
            if (!FIXNUM_P(e) && !rb_obj_is_kind_of(e, rb_cInteger)) {
                rb_raise(rb_eTypeError, "cannot exclude non Integer end value");
            }
            if (c == 0) return Qnil;
            if (!FIXNUM_P(b) && !rb_obj_is_kind_of(b,rb_cInteger)) {
                rb_raise(rb_eTypeError, "cannot exclude end value with non Integer begin value");
            }
            if (FIXNUM_P(e)) {
                return LONG2NUM(FIX2LONG(e) - 1);
            }
            return rb_funcall(e, '-', 1, INT2FIX(1));
        }
        return e;
    }
}

member?(obj) → true or false Show source

true如果obj是范围的元素则返回,false否则返回。如果开始和结束是数字,则根据值的大小进行比较。

("a".."z").include?("g")   #=> true
("a".."z").include?("A")   #=> false
("a".."z").include?("cc")  #=> false
static VALUE
range_include(VALUE range, VALUE val)
{
    VALUE beg = RANGE_BEG(range);
    VALUE end = RANGE_END(range);
    int nv = FIXNUM_P(beg) || FIXNUM_P(end) ||
             linear_object_p(beg) || linear_object_p(end);

    if (nv ||
        !NIL_P(rb_check_to_integer(beg, "to_int")) ||
        !NIL_P(rb_check_to_integer(end, "to_int"))) {
        return r_cover_p(range, beg, end, val);
    }
    else if (RB_TYPE_P(beg, T_STRING) && RB_TYPE_P(end, T_STRING)) {
        VALUE rb_str_include_range_p(VALUE beg, VALUE end, VALUE val, VALUE exclusive);
        return rb_str_include_range_p(beg, end, val, RANGE_EXCL(range));
    }
    /* TODO: ruby_frame->this_func = rb_intern("include?"); */
    return rb_call_super(1, &val);
}

min → obj Show source

min {| a,b | block } → obj

min(n) → array

min(n) {| a,b | block } → array

返回范围中的最小值。返回nil如果该范围的开始值大于结束值大。返回nil如果独占范围的开始值等于终值。

可以给定一个可选块来覆盖默认的比较方法a <=> b

(10..20).min    #=> 10
static VALUE
range_min(int argc, VALUE *argv, VALUE range)
{
    if (rb_block_given_p()) {
        return rb_call_super(argc, argv);
    }
    else if (argc != 0) {
        return range_first(argc, argv, range);
    }
    else {
        VALUE b = RANGE_BEG(range);
        VALUE e = RANGE_END(range);
        int c = rb_cmpint(rb_funcall(b, id_cmp, 1, e), b, e);

        if (c > 0 || (c == 0 && EXCL(range)))
            return Qnil;
        return b;
    }
}

size → num Show source

返回范围中元素的数量。Range的开始和结束都必须是Numeric,否则返回nil。

(10..20).size    #=> 11
('a'..'z').size  #=> nil
(-Float::INFINITY..Float::INFINITY).size #=> Infinity
static VALUE
range_size(VALUE range)
{
    VALUE b = RANGE_BEG(range), e = RANGE_END(range);
    if (rb_obj_is_kind_of(b, rb_cNumeric) && rb_obj_is_kind_of(e, rb_cNumeric)) {
        return ruby_num_interval_step_size(b, e, INT2FIX(1), EXCL(range));
    }
    return Qnil;
}

step(n=1) {| obj | block } → rng Show source

step(n=1) → an_enumerator

迭代整个范围,将每个n元素传递给块。如果开始和结束是数字,n则为每次迭代添加。否则,step调用succ遍历范围元素。

如果没有给出块,则返回一个枚举器。

range = Xs.new(1)..Xs.new(10)
range.step(2) {|x| puts x}
puts
range.step(3) {|x| puts x}

生产:

 1 x
 3 xxx
 5 xxxxx
 7 xxxxxxx
 9 xxxxxxxxx

 1 x
 4 xxxx
 7 xxxxxxx
10 xxxxxxxxxx

有关类X的定义,请参阅范围。

static VALUE
range_step(int argc, VALUE *argv, VALUE range)
{
    VALUE b, e, step, tmp;

    RETURN_SIZED_ENUMERATOR(range, argc, argv, range_step_size);

    b = RANGE_BEG(range);
    e = RANGE_END(range);
    if (argc == 0) {
        step = INT2FIX(1);
    }
    else {
        rb_scan_args(argc, argv, "01", &step);
        step = check_step_domain(step);
    }

    if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(step)) { /* fixnums are special */
        long end = FIX2LONG(e);
        long i, unit = FIX2LONG(step);

        if (!EXCL(range))
            end += 1;
        i = FIX2LONG(b);
        while (i < end) {
            rb_yield(LONG2NUM(i));
            if (i + unit < i) break;
            i += unit;
        }

    }
    else if (SYMBOL_P(b) && SYMBOL_P(e)) { /* symbols are special */
        VALUE args[2], iter[2];

        args[0] = rb_sym2str(e);
        args[1] = EXCL(range) ? Qtrue : Qfalse;
        iter[0] = INT2FIX(1);
        iter[1] = step;
        rb_block_call(rb_sym2str(b), rb_intern("upto"), 2, args, sym_step_i, (VALUE)iter);
    }
    else if (ruby_float_step(b, e, step, EXCL(range))) {
        /* done */
    }
    else if (rb_obj_is_kind_of(b, rb_cNumeric) ||
             !NIL_P(rb_check_to_integer(b, "to_int")) ||
             !NIL_P(rb_check_to_integer(e, "to_int"))) {
        ID op = EXCL(range) ? '<' : idLE;
        VALUE v = b;
        int i = 0;

        while (RTEST(rb_funcall(v, op, 1, e))) {
            rb_yield(v);
            i++;
            v = rb_funcall(b, '+', 1, rb_funcall(INT2NUM(i), '*', 1, step));
        }
    }
    else {
        tmp = rb_check_string_type(b);

        if (!NIL_P(tmp)) {
            VALUE args[2], iter[2];

            b = tmp;
            args[0] = e;
            args[1] = EXCL(range) ? Qtrue : Qfalse;
            iter[0] = INT2FIX(1);
            iter[1] = step;
            rb_block_call(b, rb_intern("upto"), 2, args, step_i, (VALUE)iter);
        }
        else {
            VALUE args[2];

            if (!discrete_object_p(b)) {
                rb_raise(rb_eTypeError, "can't iterate from %s",
                         rb_obj_classname(b));
            }
            args[0] = INT2FIX(1);
            args[1] = step;
            range_each_func(range, step_i, (VALUE)args);
        }
    }
    return range;
}

to_json(*args) Show source

使用a包含first(整数),last(整数)和exclude_end?(布尔)作为JSON字符串的参数的JSON数组存储类名称(Range)。

# File ext/json/lib/json/add/range.rb, line 26
def to_json(*args)
  as_json.to_json(*args)
end

to_s → string Show source

将此范围对象转换为可打印的形式(使用to_s来转换开始和结束对象)。

static VALUE
range_to_s(VALUE range)
{
    VALUE str, str2;

    str = rb_obj_as_string(RANGE_BEG(range));
    str2 = rb_obj_as_string(RANGE_END(range));
    str = rb_str_dup(str);
    rb_str_cat(str, "...", EXCL(range) ? 3 : 2);
    rb_str_append(str, str2);
    OBJ_INFECT(str, range);

    return str;
}

范围 | Range相关

Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct