[RUBY] Verhalten, wenn jedes im umgekehrten Bereich ausgeführt wird

Als ich mich umdrehte, tat ich nichts und bekam keinen Fehler, und ich war süchtig danach, weil die Verarbeitung so weiterging, wie sie war, also machte ich ein Memorandum.

Bereichsinstanziierung

Im Fall von Startpunkt <Endpunkt, Startpunkt> Endpunkt kann die Instanziierung problemlos erstellt werden.

aaa = Range.new(1,5)
=> 1..5

bbb = 1..5
=> 1..5
ccc = Range.new(5,1)
=> 5..1

ddd = 5..1
=> 5..1

Range#each

Bereich # jedes Verhalten

Das Problem ist, wenn Sie jeden Bereich in umgekehrter Reihenfolge drehen.

aaa.each {|i| puts i}
1
2
3
4
5
=> 1..5
ccc.each {|i|puts i}
=> 5..1

Beschreibung des Bereichs # jeweils

Laut Rurima wird Range # jeweils mit succ iteriert. https://docs.ruby-lang.org/ja/latest/method/Range/i/each.html

Wenn man sich die Beschreibung von succ für Integer ansieht, scheint es, dass einfach die nächste Ganzzahl zurückgegeben wird.

aaa.begin.class
=> Integer

https://docs.ruby-lang.org/ja/2.5.0/method/Integer/i/next.html

aaa.begin
=> 1
aaa.begin.succ
=> 2
ccc.begin
=> 5
ccc.begin.succ
=> 6

Implementierung von Range # jeweils

Wahrscheinlich wird statischer VALUE range_each (VALUE range) aufgerufen, und da die while-Bedingung danach nicht erfüllt ist, scheint die Verarbeitung abgeschlossen zu sein, ohne auch nur eine Runde zu schleifen.

https://github.com/ruby/ruby/blob/trunk/range.c#L833

static VALUE
range_each(VALUE range)
{
//...Kürzung
	    if (!NIL_P(end))
		range_each_func(range, each_i, 0);
	    else
		for (;; beg = rb_funcallv(beg, id_succ, 0, 0))
		    rb_yield(beg);
//...Kürzung
}

https://github.com/ruby/ruby/blob/trunk/range.c#L239

static void
range_each_func(VALUE range, int (*func)(VALUE, VALUE), VALUE arg)
{
    int c;
    VALUE b = RANGE_BEG(range);
    VALUE e = RANGE_END(range);
    VALUE v = b;

    if (EXCL(range)) {
	while (r_less(v, e) < 0) {
	    if ((*func)(v, arg)) break;
	    v = rb_funcallv(v, id_succ, 0, 0);
	}
    }
    else {
	while ((c = r_less(v, e)) <= 0) {
	    if ((*func)(v, arg)) break;
	    if (!c) break;
	    v = rb_funcallv(v, id_succ, 0, 0);
	}
    }
}

https://github.com/ruby/ruby/blob/trunk/range.c#L157

/* compares _a_ and _b_ and returns:
 * < 0: a < b
 * = 0: a = b
 * > 0: a > b or non-comparable
 */
static int
r_less(VALUE a, VALUE b)
{
    VALUE r = rb_funcall(a, id_cmp, 1, b);

    if (NIL_P(r))
	return INT_MAX;
    return rb_cmpint(r, a, b);
}

Recommended Posts

Verhalten, wenn jedes im umgekehrten Bereich ausgeführt wird
Verhalten, wenn Platzhalter (**) in Ruby angegeben ist
Wenn das Projekt nicht in Eclipse angezeigt wird
Ebean.update () wird im geerbten Modell nicht ausgeführt.
ORA-08177, wenn Spring Batch kontinuierlich in Oracle ausgeführt wird
Bis der Code ausgeführt wird
Das Verhalten der Klasse # getClassLoader ändert sich abhängig davon, ob sie in der IDE oder in der JAR ausgeführt wird.
So geben Sie den Wert aus, wenn sich ein Array im Array befindet
Reihenfolge der Verarbeitung im Programm
Ändern Sie die Verarbeitung, wenn Sie für jede Liste auf die Schaltfläche in RecyclerView klicken
Fehler, wenn das in SpringWebFlux verwendete Mitglied der Entity-Klasse endgültig ist
Wenn der Bean-Klassenname dupliziert wird
[Rails] Annotate wird bei der Migration nicht ausgeführt
Spring Autowired wird im Konstruktor geschrieben
Was ist die Hauptmethode in Java?
Möglichkeit bei der Bereitstellung auf EC2, aber im Fehlerprotokoll wird nichts angezeigt
Festlegen, wann in junit "Der Konstruktor Empty () ist nicht sichtbar" auftritt