Spec-Zone.ru › Ruby 3.2

class Numeric

Parent:
Object
Included modules:
Comparable

Numeric - это класс, от которого должны наследоваться все числовые классы более высокого уровня.

Numeric позволяет создавать экземпляры объектов, выделяемых в куче. Другие основные числовые классы, такие как Integer, реализованы как немедленные, что означает, что каждый Integer представляет собой один неизменяемый объект, который всегда передается по значению.

a = 1
1.object_id == a.object_id   #=> true

Может существовать только один экземпляр целого числа 1, например. Ruby гарантирует это, предотвращая создание экземпляров. Если попытка дублирования будет предпринята, будет возвращен тот же экземпляр.

Integer.new(1)                   #=> NoMethodError: undefined method `new' for Integer:Class
1.dup                            #=> 1
1.object_id == 1.dup.object_id   #=> true

По этой причине Numeric следует использовать при определении других числовых классов.

Классы, которые наследуются от Numeric, должны реализовывать coerce, который возвращает двухэлементный Array, содержащий объект, преобразованный в экземпляр нового класса, и self (см. coerce).

Наследующие классы также должны реализовывать методы арифметических операторов (+, -, * и /) и оператор <=> (см. Comparable). Эти методы могут полагаться на coerce для обеспечения взаимодействия с экземплярами других числовых классов.

class Tally < Numeric
  def initialize(string)
    @string = string
  end

  def to_s
    @string
  end

  def to_i
    @string.size
  end

  def coerce(other)
    [self.class.new('|' * other.to_i), self]
  end

  def <=>(other)
    to_i <=> other.to_i
  end

  def +(other)
    self.class.new('|' * (to_i + other.to_i))
  end

  def -(other)
    self.class.new('|' * (to_i - other.to_i))
  end

  def *(other)
    self.class.new('|' * (to_i * other.to_i))
  end

  def /(other)
    self.class.new('|' * (to_i / other.to_i))
  end
end

tally = Tally.new('||')
puts tally * 2            #=> "||||"
puts tally > 1            #=> true

Что здесь

Сначала, что находится в другом месте. Класс Numeric:

  • Наследуется от class Object.

  • Включает module Comparable.

Здесь класс Numeric предоставляет методы для:

  • Запроса

  • Сравнения

  • Преобразования

  • Других операций

Запрос

  • finite?: Возвращает true, если self не является бесконечным или не числом.

  • infinite?: Возвращает -1, nil или +1, в зависимости от того, является ли self -Infinity<tt>, finite, or <tt>+Infinity.

  • integer?: Возвращает, является ли self целым числом.

  • negative?: Возвращает, является ли self отрицательным.

  • nonzero?: Возвращает, является ли self не нулем.

  • positive?: Возвращает, является ли self положительным.

  • real?: Возвращает, является ли self вещественным значением.

  • zero?: Возвращает, является ли self нулем.

Сравнение

  • <=>: Возвращает:

    • -1, если self меньше заданного значения.

    • 0, если self равно заданному значению.

    • 1, если self больше заданного значения.

    • nil, если self и заданное значение не сравнимы.

  • eql?: Возвращает, имеют ли self и заданное значение одинаковое значение и тип.

Преобразование

  • % (псевдоним modulo): Возвращает остаток от деления self на заданное значение.

  • -@: Возвращает значение self, взятое с обратным знаком.

  • abs (псевдоним magnitude): Возвращает абсолютное значение self.

  • abs2: Возвращает квадрат self.

  • angle (псевдоним arg и phase): Возвращает 0, если self положительно, Math::PI в противном случае.

  • ceil: Возвращает наименьшее число, большее или равное self, с заданной точностью.

  • coerce: Возвращает массив [coerced_self, coerced_other] для заданного другого значения.

  • conj (псевдоним conjugate): Возвращает комплексно сопряженное число self.

  • denominator: Возвращает знаменатель (всегда положительный) Rational представления self.

  • div: Возвращает значение self, деленное на заданное значение и преобразованное в целое число.

  • divmod: Возвращает массив [quotient, modulus], полученный в результате деления self на заданный делитель.

  • fdiv: Возвращает результат деления self на заданный делитель в виде Float.

  • floor: Возвращает наибольшее число, меньшее или равное self, с заданной точностью.

  • i: Возвращает Complex объект Complex(0, self). заданное значение.

  • imaginary (псевдоним imag): Возвращает мнимую часть self.

  • numerator: Возвращает числитель Rational представления self; имеет тот же знак, что и self.

  • polar: Возвращает массив [self.abs, self.arg].

  • quo: Возвращает значение self, деленное на заданное значение.

  • real: Возвращает вещественную часть self.

  • rect (псевдоним rectangular): Возвращает массив [self, 0].

  • remainder: Возвращает self-arg*(self/arg).truncate для заданного arg.

  • round: Возвращает значение self, округленное до ближайшего значения с заданной точностью.

  • to_c: Возвращает Complex представление self.

  • to_int: Возвращает Integer представление self, усекая при необходимости.

  • truncate: Возвращает self, усеченное (в сторону нуля) с заданной точностью.

Другие операции

  • clone: Возвращает self; не допускает замораживания.

  • dup (псевдоним +@): Возвращает self.

  • step: Вызывает заданный блок с последовательностью указанных чисел.

Методы экземпляров публичного класса

self % other → real_numeric Показать исходный код
static VALUE
num_modulo(VALUE x, VALUE y)
{
    VALUE q = num_funcall1(x, id_div, y);
    return rb_funcall(x, '-', 1,
                      rb_funcall(y, '*', 1, q));
}

Возвращает остаток от деления self по модулю other в виде вещественного числа.

Из классов Ядра и Стандартной библиотеки только Rational использует эту реализацию.

Для рациональных r и вещественных чисел n, эти выражения эквивалентны:

r % n
r-n*(r/n).floor
r.divmod(n)[1]

См. Numeric#divmod.

Примеры:

r = Rational(1, 2)    # => (1/2)
r2 = Rational(2, 3)   # => (2/3)
r % r2                # => (1/2)
r % 2                 # => (1/2)
r % 2.0               # => 0.5

r = Rational(301,100) # => (301/100)
r2 = Rational(7,5)    # => (7/5)
r % r2                # => (21/100)
r % -r2               # => (-119/100)
(-r) % r2             # => (119/100)
(-r) %-r2             # => (-21/100)

Numeric#modulo — псевдоним для Numeric#%.

Также используется как: modulo
+self → self Показать исходный код
static VALUE
num_uplus(VALUE num)
{
    return num;
}

Возвращает self.

-self → numeric Показать исходный код
static VALUE
num_uminus(VALUE num)
{
    VALUE zero;

    zero = INT2FIX(0);
    do_coerce(&zero, &num, TRUE);

    return num_funcall1(zero, '-', num);
}

Унарный минус — возвращает значение объекта, смененного на противоположное.

self <=> other → zero or nil Показать исходный код
static VALUE
num_cmp(VALUE x, VALUE y)
{
    if (x == y) return INT2FIX(0);
    return Qnil;
}

Возвращает ноль, если self равно other, и nil в противном случае.

Ни один подкласс в Ядре или Стандартной библиотеке Ruby не использует эту реализацию.

abs → numeric Показать исходный код
static VALUE
num_abs(VALUE num)
{
    if (rb_num_negative_int_p(num)) {
        return num_funcall0(num, idUMinus);
    }
    return num;
}

Возвращает абсолютное значение self.

12.abs        #=> 12
(-34.56).abs  #=> 34.56
-34.56.abs    #=> 34.56

Numeric#magnitude — псевдоним для Numeric#abs.

Также используется как: magnitude
abs2 → real Показать исходный код
static VALUE
numeric_abs2(VALUE self)
{
    return f_mul(self, self);
}

Возвращает квадрат значения.

angle → 0 or float

Возвращает 0, если значение положительное, и pi в противном случае.

Псевдоним для: arg
arg → 0 or float Показать исходный код
static VALUE
numeric_arg(VALUE self)
{
    if (f_positive_p(self))
        return INT2FIX(0);
    return DBL2NUM(M_PI);
}

Возвращает 0, если значение положительное, и pi в противном случае.

Также используется как: angle, phase
ceil(digits = 0) → integer or float Показать исходный код
static VALUE
num_ceil(int argc, VALUE *argv, VALUE num)
{
    return flo_ceil(argc, argv, rb_Float(num));
}

Возвращает наименьшее число, которое больше или равно self с точностью до digits десятичных знаков.

Numeric выполняет это, преобразуя self в Float и вызывая Float#ceil.

clone(freeze: true) → self Показать исходный код
static VALUE
num_clone(int argc, VALUE *argv, VALUE x)
{
    return rb_immutable_obj_clone(argc, argv, x);
}

Возвращает self.

Вызывает исключение, если значение для freeze не является ни true, ни nil.

Связанно с: Numeric#dup.

coerce(other) → array Показать исходный код
static VALUE
num_coerce(VALUE x, VALUE y)
{
    if (CLASS_OF(x) == CLASS_OF(y))
        return rb_assoc_new(y, x);
    x = rb_Float(x);
    y = rb_Float(y);
    return rb_assoc_new(y, x);
}

Возвращает массив из двух элементов, содержащих два числовых элемента, сформированных из двух операндов self и other, одного совместимого типа.

Из классов Ядра и Стандартной библиотеки Integer, Rational и Complex используют эту реализацию.

Примеры:

i = 2                    # => 2
i.coerce(3)              # => [3, 2]
i.coerce(3.0)            # => [3.0, 2.0]
i.coerce(Rational(1, 2)) # => [0.5, 2.0]
i.coerce(Complex(3, 4))  # Raises RangeError.

r = Rational(5, 2)       # => (5/2)
r.coerce(2)              # => [(2/1), (5/2)]
r.coerce(2.0)            # => [2.0, 2.5]
r.coerce(Rational(2, 3)) # => [(2/3), (5/2)]
r.coerce(Complex(3, 4))  # => [(3+4i), ((5/2)+0i)]

c = Complex(2, 3)        # => (2+3i)
c.coerce(2)              # => [(2+0i), (2+3i)]
c.coerce(2.0)            # => [(2.0+0i), (2+3i)]
c.coerce(Rational(1, 2)) # => [((1/2)+0i), (2+3i)]
c.coerce(Complex(3, 4))  # => [(3+4i), (2+3i)]

Вызывает исключение, если преобразование типа не выполняется.

conj → self
Псевдоним для: conjugate
conjugate → self Показать исходный код
# File numeric.rb, line 76
def conjugate
  self
end

Возвращает self.

Также используется как: conj
denominator → integer Показать исходный код
static VALUE
numeric_denominator(VALUE self)
{
    return f_denominator(f_to_r(self));
}

Возвращает знаменатель (всегда положительный).

div(other) → integer Показать исходный код
static VALUE
num_div(VALUE x, VALUE y)
{
    if (rb_equal(INT2FIX(0), y)) rb_num_zerodiv();
    return rb_funcall(num_funcall1(x, '/', y), rb_intern("floor"), 0);
}

Возвращает частное self/other в виде целого числа (через floor), используя метод / в производном классе self. (Сам Numeric не определяет метод /.)

Из классов Ядра и Стандартной библиотеки только Float и Rational используют эту реализацию.

divmod(other) → array Показать исходный код
static VALUE
num_divmod(VALUE x, VALUE y)
{
    return rb_assoc_new(num_div(x, y), num_modulo(x, y));
}

Возвращает массив из двух элементов [q, r], где

q = (self/other).floor                  # Quotient
r = self % other                        # Remainder

Из классов Ядра и Стандартной библиотеки только Rational использует эту реализацию.

Примеры:

Rational(11, 1).divmod(4)               # => [2, (3/1)]
Rational(11, 1).divmod(-4)              # => [-3, (-1/1)]
Rational(-11, 1).divmod(4)              # => [-3, (1/1)]
Rational(-11, 1).divmod(-4)             # => [2, (-3/1)]

Rational(12, 1).divmod(4)               # => [3, (0/1)]
Rational(12, 1).divmod(-4)              # => [-3, (0/1)]
Rational(-12, 1).divmod(4)              # => [-3, (0/1)]
Rational(-12, 1).divmod(-4)             # => [3, (0/1)]

Rational(13, 1).divmod(4.0)             # => [3, 1.0]
Rational(13, 1).divmod(Rational(4, 11)) # => [35, (3/11)]
dup → self Показать исходный код
static VALUE
num_dup(VALUE x)
{
    return x;
}

Возвращает self.

Связанно с: Numeric#clone.

eql?(other) → true or false Показать исходный код
static VALUE
num_eql(VALUE x, VALUE y)
{
    if (TYPE(x) != TYPE(y)) return Qfalse;

    if (RB_BIGNUM_TYPE_P(x)) {
        return rb_big_eql(x, y);
    }

    return rb_equal(x, y);
}

Возвращает true , если self и other — объекты одного типа с равными значениями.

Из классов Ядра и Стандартной библиотеки только Integer, Rational и Complex используют эту реализацию.

Примеры:

1.eql?(1)              # => true
1.eql?(1.0)            # => false
1.eql?(Rational(1, 1)) # => false
1.eql?(Complex(1, 0))  # => false

Метод eql? отличается от +==+ тем, что eql? требует соответствия типов, в то время как +==+ — нет.

fdiv(other) → float Показать исходный код
static VALUE
num_fdiv(VALUE x, VALUE y)
{
    return rb_funcall(rb_Float(x), '/', 1, y);
}

Возвращает частное self/other в виде вещественного числа, используя метод / в производном классе self. (Сам Numeric не определяет метод /.)

Из классов Ядра и Стандартной библиотеки только BigDecimal использует эту реализацию.

finite? → true или false Показать исходный код
# File numeric.rb, line 41
def finite?
  true
end

Возвращает true, если num является конечным числом, в противном случае возвращает false.

floor(digits = 0) → целое число или число с плавающей точкой Показать исходный код
static VALUE
num_floor(int argc, VALUE *argv, VALUE num)
{
    return flo_floor(argc, argv, rb_Float(num));
}

Возвращает наибольшее число, меньшее или равное self с точностью до digits десятичных знаков.

Numeric реализует это, преобразуя self в Float и вызывая Float#floor.

i → комплексное число Показать исходный код
static VALUE
num_imaginary(VALUE num)
{
    return rb_complex_new(INT2FIX(0), num);
}

Возвращает Complex(0, self):

2.i              # => (0+2i)
-2.i             # => (0-2i)
2.0.i            # => (0+2.0i)
Rational(1, 2).i # => (0+(1/2)*i)
Complex(3, 4).i  # Raises NoMethodError.
imag → 0
Псевдоним для: imaginary
imaginary → 0 Показать исходный код
# File numeric.rb, line 63
def imaginary
  0
end

Возвращает ноль.

Также псевдоним для: imag
infinite? → -1, 1 или nil Показать исходный код
# File numeric.rb, line 52
def infinite?
  nil
end

Возвращает -1, 1 или nil в зависимости от того, является ли значение конечным, бесконечным или неопределенным.

integer? → true или false Показать исходный код
# File numeric.rb, line 31
def integer?
  false
end

Возвращает true, если num является Integer.

1.0.integer?   #=> false
1.integer?     #=> true
magnitude()

Возвращает абсолютное значение self.

12.abs        #=> 12
(-34.56).abs  #=> 34.56
-34.56.abs    #=> 34.56

Numeric#magnitude является псевдонимом для Numeric#abs.

Псевдоним для: abs
modulo(p1)

Возвращает остаток от деления self на other как вещественное число.

Из классов Ядра и Стандартной библиотеки только Rational использует эту реализацию.

Для рациональных r и вещественного числа n, эти выражения эквивалентны:

r % n
r-n*(r/n).floor
r.divmod(n)[1]

См. Numeric#divmod.

Примеры:

r = Rational(1, 2)    # => (1/2)
r2 = Rational(2, 3)   # => (2/3)
r % r2                # => (1/2)
r % 2                 # => (1/2)
r % 2.0               # => 0.5

r = Rational(301,100) # => (301/100)
r2 = Rational(7,5)    # => (7/5)
r % r2                # => (21/100)
r % -r2               # => (-119/100)
(-r) % r2             # => (119/100)
(-r) %-r2             # => (-21/100)

Numeric#modulo является псевдонимом для Numeric#%.

Псевдоним для: %
negative? → true или false Показать исходный код
static VALUE
num_negative_p(VALUE num)
{
    return RBOOL(rb_num_negative_int_p(num));
}

Возвращает true, если self меньше 0, false в противном случае.

nonzero? → self или nil Показать исходный код
static VALUE
num_nonzero_p(VALUE num)
{
    if (RTEST(num_funcall0(num, rb_intern("zero?")))) {
        return Qnil;
    }
    return num;
}

Возвращает self, если self не равно нулю, nil в противном случае; использует метод zero? для оценки.

Возвращаемое значение позволяет цепочке методов.

a = %w[z Bb bB bb BB a aA Aa AA A]
a.sort {|a, b| (a.downcase <=> b.downcase).nonzero? || a <=> b }
# => ["A", "a", "AA", "Aa", "aA", "BB", "Bb", "bB", "bb", "z"]

Из классов Ядра и Стандартной библиотеки Integer, Float, Rational и Complex используют эту реализацию.

numerator → целое число Показать исходный код
static VALUE
numeric_numerator(VALUE self)
{
    return f_numerator(f_to_r(self));
}

Возвращает числитель.

phase()

Возвращает 0, если значение положительное, и π в противном случае.

Псевдоним для: arg
polar → массив Показать исходный код
static VALUE
numeric_polar(VALUE self)
{
    VALUE abs, arg;

    if (RB_INTEGER_TYPE_P(self)) {
        abs = rb_int_abs(self);
        arg = numeric_arg(self);
    }
    else if (RB_FLOAT_TYPE_P(self)) {
        abs = rb_float_abs(self);
        arg = float_arg(self);
    }
    else if (RB_TYPE_P(self, T_RATIONAL)) {
        abs = rb_rational_abs(self);
        arg = numeric_arg(self);
    }
    else {
        abs = f_abs(self);
        arg = f_arg(self);
    }
    return rb_assoc_new(abs, arg);
}

Возвращает массив; [num.abs, num.arg].

positive? → true или false Показать исходный код
static VALUE
num_positive_p(VALUE num)
{
    const ID mid = '>';

    if (FIXNUM_P(num)) {
        if (method_basic_p(rb_cInteger))
            return RBOOL((SIGNED_VALUE)num > (SIGNED_VALUE)INT2FIX(0));
    }
    else if (RB_BIGNUM_TYPE_P(num)) {
        if (method_basic_p(rb_cInteger))
            return RBOOL(BIGNUM_POSITIVE_P(num) && !rb_bigzero_p(num));
    }
    return rb_num_compare_with_zero(num, mid);
}

Возвращает true, если self больше 0, false в противном случае.

quo(int_or_rat) → рац Показать исходный код
quo(flo) → flo
VALUE
rb_numeric_quo(VALUE x, VALUE y)
{
    if (RB_TYPE_P(x, T_COMPLEX)) {
        return rb_complex_div(x, y);
    }

    if (RB_FLOAT_TYPE_P(y)) {
        return rb_funcallv(x, idFdiv, 1, &y);
    }

    x = rb_convert_type(x, T_RATIONAL, "Rational", "to_r");
    return rb_rational_div(x, y);
}

Возвращает наиболее точное деление (рациональное для целых чисел, число с плавающей точкой для чисел с плавающей точкой).

real → self Показать исходный код
# File numeric.rb, line 18
def real
  self
end

Возвращает self.

real? → true или false Показать исходный код
# File numeric.rb, line 8
def real?
  true
end

Возвращает true, если num является вещественным числом (т.е. не Complex).

rect → массив

Возвращает массив; [num, 0].

Псевдоним для: rectangular
rectangular → массив Показать исходный код
static VALUE
numeric_rect(VALUE self)
{
    return rb_assoc_new(self, INT2FIX(0));
}

Возвращает массив; [num, 0].

Также псевдоним для: rect
remainder(other) → вещественное число Показать исходный код
static VALUE
num_remainder(VALUE x, VALUE y)
{
    VALUE z = num_funcall1(x, '%', y);

    if ((!rb_equal(z, INT2FIX(0))) &&
        ((rb_num_negative_int_p(x) &&
          rb_num_positive_int_p(y)) ||
         (rb_num_positive_int_p(x) &&
          rb_num_negative_int_p(y)))) {
        if (RB_FLOAT_TYPE_P(y)) {
            if (isinf(RFLOAT_VALUE(y))) {
                return x;
            }
        }
        return rb_funcall(z, '-', 1, y);
    }
    return z;
}

Возвращает остаток от деления self на other.

Из классов Ядра и Стандартной библиотеки только Float и Rational используют эту реализацию.

Примеры:

11.0.remainder(4)              # => 3.0
11.0.remainder(-4)             # => 3.0
-11.0.remainder(4)             # => -3.0
-11.0.remainder(-4)            # => -3.0

12.0.remainder(4)              # => 0.0
12.0.remainder(-4)             # => 0.0
-12.0.remainder(4)             # => -0.0
-12.0.remainder(-4)            # => -0.0

13.0.remainder(4.0)            # => 1.0
13.0.remainder(Rational(4, 1)) # => 1.0

Rational(13, 1).remainder(4)   # => (1/1)
Rational(13, 1).remainder(-4)  # => (1/1)
Rational(-13, 1).remainder(4)  # => (-1/1)
Rational(-13, 1).remainder(-4) # => (-1/1)
round(digits = 0) → целое число или число с плавающей точкой Показать исходный код
static VALUE
num_round(int argc, VALUE* argv, VALUE num)
{
    return flo_round(argc, argv, rb_Float(num));
}

Возвращает self, округленное до ближайшего значения с точностью до digits десятичных знаков.

Numeric реализует это, преобразуя self в Float и вызывая Float#round.

END_OF_DOCUMENT_MARKER
step(to = nil, by = 1) {|n| ... } → self Показать исходный код
step(to = nil, by = 1) → перечислитель
step(to = nil, by: 1) {|n| ... } → self
step(to = nil, by: 1) → перечислитель
step(by: 1, to: ) {|n| ... } → self
step(by: 1, to: ) → перечислитель
step(by: , to: nil) {|n| ... } → self
step(by: , to: nil) → перечислитель
static VALUE
num_step(int argc, VALUE *argv, VALUE from)
{
    VALUE to, step;
    int desc, inf;

    if (!rb_block_given_p()) {
        VALUE by = Qundef;

        num_step_extract_args(argc, argv, &to, &step, &by);
        if (!UNDEF_P(by)) {
            step = by;
        }
        if (NIL_P(step)) {
            step = INT2FIX(1);
        }
        else if (rb_equal(step, INT2FIX(0))) {
            rb_raise(rb_eArgError, "step can't be 0");
        }
        if ((NIL_P(to) || rb_obj_is_kind_of(to, rb_cNumeric)) &&
            rb_obj_is_kind_of(step, rb_cNumeric)) {
            return rb_arith_seq_new(from, ID2SYM(rb_frame_this_func()), argc, argv,
                                    num_step_size, from, to, step, FALSE);
        }

        return SIZED_ENUMERATOR(from, 2, ((VALUE [2]){to, step}), num_step_size);
    }

    desc = num_step_scan_args(argc, argv, &to, &step, TRUE, FALSE);
    if (rb_equal(step, INT2FIX(0))) {
        inf = 1;
    }
    else if (RB_FLOAT_TYPE_P(to)) {
        double f = RFLOAT_VALUE(to);
        inf = isinf(f) && (signbit(f) ? desc : !desc);
    }
    else inf = 0;

    if (FIXNUM_P(from) && (inf || FIXNUM_P(to)) && FIXNUM_P(step)) {
        long i = FIX2LONG(from);
        long diff = FIX2LONG(step);

        if (inf) {
            for (;; i += diff)
                rb_yield(LONG2FIX(i));
        }
        else {
            long end = FIX2LONG(to);

            if (desc) {
                for (; i >= end; i += diff)
                    rb_yield(LONG2FIX(i));
            }
            else {
                for (; i <= end; i += diff)
                    rb_yield(LONG2FIX(i));
            }
        }
    }
    else if (!ruby_float_step(from, to, step, FALSE, FALSE)) {
        VALUE i = from;

        if (inf) {
            for (;; i = rb_funcall(i, '+', 1, step))
                rb_yield(i);
        }
        else {
            ID cmp = desc ? '<' : '>';

            for (; !RTEST(rb_funcall(i, cmp, 1, to)); i = rb_funcall(i, '+', 1, step))
                rb_yield(i);
        }
    }
    return from;
}
Generates a sequence of numbers; with a block given, traverses the sequence.

Of the Core and Standard Library classes,
Integer, Float, and Rational use this implementation.

A quick example:

  squares = []
  1.step(by: 2, to: 10) {|i| squares.push(i*i) }
  squares # => [1, 9, 25, 49, 81]

The generated sequence:

- Begins with +self+.
- Continues at intervals of +step+ (which may not be zero).
- Ends with the last number that is within or equal to +limit+;
  that is, less than or equal to +limit+ if +step+ is positive,
  greater than or equal to +limit+ if +step+ is negative.
  If +limit+ is not given, the sequence is of infinite length.

If a block is given, calls the block with each number in the sequence;
returns +self+.  If no block is given, returns an Enumerator::ArithmeticSequence.

<b>Keyword Arguments</b>

With keyword arguments +by+ and +to+,
their values (or defaults) determine the step and limit:

  # Both keywords given.
  squares = []
  4.step(by: 2, to: 10) {|i| squares.push(i*i) }    # => 4
  squares # => [16, 36, 64, 100]
  cubes = []
  3.step(by: -1.5, to: -3) {|i| cubes.push(i*i*i) } # => 3
  cubes   # => [27.0, 3.375, 0.0, -3.375, -27.0]
  squares = []
  1.2.step(by: 0.2, to: 2.0) {|f| squares.push(f*f) }
  squares # => [1.44, 1.9599999999999997, 2.5600000000000005, 3.24, 4.0]

  squares = []
  Rational(6/5).step(by: 0.2, to: 2.0) {|r| squares.push(r*r) }
  squares # => [1.0, 1.44, 1.9599999999999997, 2.5600000000000005, 3.24, 4.0]

  # Only keyword to given.
  squares = []
  4.step(to: 10) {|i| squares.push(i*i) }           # => 4
  squares # => [16, 25, 36, 49, 64, 81, 100]
  # Only by given.

  # Only keyword by given
  squares = []
  4.step(by:2) {|i| squares.push(i*i); break if i > 10 }
  squares # => [16, 36, 64, 100, 144]

  # No block given.
  e = 3.step(by: -1.5, to: -3) # => (3.step(by: -1.5, to: -3))
  e.class                      # => Enumerator::ArithmeticSequence

<b>Positional Arguments</b>

With optional positional arguments +limit+ and +step+,
their values (or defaults) determine the step and limit:

  squares = []
  4.step(10, 2) {|i| squares.push(i*i) }    # => 4
  squares # => [16, 36, 64, 100]
  squares = []
  4.step(10) {|i| squares.push(i*i) }
  squares # => [16, 25, 36, 49, 64, 81, 100]
  squares = []
  4.step {|i| squares.push(i*i); break if i > 10 }  # => nil
  squares # => [16, 25, 36, 49, 64, 81, 100, 121]

Примечания к реализации

If all the arguments are integers, the loop operates using an integer
counter.

If any of the arguments are floating point numbers, all are converted
to floats, and the loop is executed
<i>floor(n + n*Float::EPSILON) + 1</i> times,
where <i>n = (limit - self)/step</i>.
to_c → комплексное Показать исходный код
static VALUE
numeric_to_c(VALUE self)
{
    return rb_complex_new1(self);
}

Возвращает значение в виде комплексного числа.

to_int → целое Показать исходный код
static VALUE
num_to_int(VALUE num)
{
    return num_funcall0(num, id_to_i);
}

Возвращает self как целое число; выполняет преобразование с помощью метода to_i в производном классе.

Из классов Ядра и Стандартной библиотеки только Rational и Complex используют эту реализацию.

Примеры:

Rational(1, 2).to_int # => 0
Rational(2, 1).to_int # => 2
Complex(2, 0).to_int  # => 2
Complex(2, 1)         # Raises RangeError (non-zero imaginary part)
truncate(digits = 0) → целое или число с плавающей точкой Показать исходный код
static VALUE
num_truncate(int argc, VALUE *argv, VALUE num)
{
    return flo_truncate(argc, argv, rb_Float(num));
}

Возвращает self, усеченное (к нулю) с точностью digits десятичных знаков.

Numeric реализует это, преобразуя self в Float и вызывая Float#truncate.

zero? → true или false Показать исходный код
static VALUE
num_zero_p(VALUE num)
{
    return rb_equal(num, INT2FIX(0));
}

Возвращает true, если zero имеет нулевое значение, false в противном случае.

Из классов Ядра и Стандартной библиотеки только Rational и Complex используют эту реализацию.

Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API