Verketten von Enumeratoren, die mehrere Argumente ergeben

8

Ich versuche herauszufinden, wie Ruby Verkettungs-Enumeratoren behandelt, die mehrere Argumente liefern. Schauen Sie sich dieses Snippet an:

%Vor%

Warum liefert select die Argumente als Array, während map sie als zwei separate Argumente liefert?

    
Ben Weissmann 24.01.2013, 02:22
quelle

4 Antworten

2

Aus dem bisherigen Diskurs folgt, dass wir den Quellcode analysieren können, aber wir kennen das Warum nicht. Ruby-Core-Team ist relativ sehr reaktionsschnell. Ich empfehle Ihnen, sich unter Ссылка anzumelden und dort einen Fehlerbericht zu posten. Sie werden sich dieses Problem höchstwahrscheinlich innerhalb weniger Wochen ansehen, und Sie können wahrscheinlich erwarten, dass es in der nächsten Nebenversion von Ruby korrigiert wird. (Das heißt, es sei denn, es gibt eine Entwurfslogik, die uns unbekannt ist, um die Dinge so zu halten, wie sie sind.)

    
Boris Stitnicky 24.01.2013, 04:36
quelle
4

Versuchen Sie:

%Vor%

map dekonstruiert automatisch die an ihn übergebenen Werte. Die nächste Frage ist warum diese Dekonstruktion durchführt und select nicht?

Wenn Sie sich die Quelle auf der Rdoc-Seite von Array ansehen , Re praktisch identisch, select unterscheidet sich nur dadurch, dass es einen Test auf den erzielten Wert durchführt. Irgendwo muss etwas passieren.

Wenn wir uns die Rubinius-Quelle ansehen (hauptsächlich weil ich bin besser mit Ruby als C;) für map (aliased von collect ) zeigt es uns:

%Vor%

Damit werden die Argumente auf dem Weg durchgespielt, während ausgewählt wird > (Alias ​​von find_all ) nicht:

%Vor%

Noch einmal, die Designentscheidung bezüglich warum liegt jenseits meiner. Sie müssen herausfinden, wer es geschrieben hat, vielleicht fragen Sie Matz:)

Ich sollte hinzufügen, schauen Sie sich die Rubinius Quelle wieder an, map actual splats auf each und auf yield , ich verstehe nicht, warum Sie beides tun würden, wenn nur die yield splat wird benötigt:

%Vor%

wobei select nicht.

%Vor%     
iain 24.01.2013 03:17
quelle
2

Laut der MRI-Quelle scheint es, als ob der Iterator in select splats verwendet wurde seine Argumente kommen herein, aber map nicht und übergibt sie unverpackt; Der Block im letzten Fall ignoriert die anderen Argumente stillschweigend.

Der in select verwendete Iterator:

%Vor%

Der in map verwendete Iterator:

%Vor%

Ich bin ziemlich sicher, dass das Makro ENUM_WANT_SVALUE() verwendet wird, um den in den Block übergebenen Wert in einen Splat-Array-Wert umzuwandeln (im Gegensatz zu einem Tupel mit den letzteren Argumenten, die stillschweigend ignoriert werden). Das heißt, ich weiß nicht, warum es so entworfen wurde.

    
Platinum Azure 24.01.2013 03:24
quelle
2

Sehen wir uns die MRT-Quelle in enum.c an. Wie @PlatinumAzure sagte, passiert die Magie in ENUM_WANT_SVALUE() :

%Vor%

Und wir können dieses Makro tatsächlich finden: do {i = rb_enum_values_pack(argc, argv);}while(0) .

Also gehen wir weiter in rb_enum_values_pack function:

%Vor%

Siehe? Die Argumente werden von rb_ary_new4 gepackt, das in array.c .     

halfelf 24.01.2013 03:36
quelle

Tags und Links