Last active
December 15, 2015 20:19
-
-
Save phiggins/5317981 to your computer and use it in GitHub Desktop.
Patch to allow Ruby's Array#map to take a symbol.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ ./ruby -I. -Ilib/ -w map_symbol_bench.rb | |
Rehearsal -------------------------------------------- | |
nil 0.050000 0.000000 0.050000 ( 0.046891) | |
identity 0.880000 0.000000 0.880000 ( 0.887874) | |
block 1.080000 0.000000 1.080000 ( 1.078556) | |
to_proc 0.990000 0.000000 0.990000 ( 0.996956) | |
----------------------------------- total: 3.000000sec | |
user system total real | |
nil 0.040000 0.000000 0.040000 ( 0.045237) | |
identity 0.860000 0.000000 0.860000 ( 0.866740) | |
block 1.070000 0.000000 1.070000 ( 1.066750) | |
to_proc 0.990000 0.000000 0.990000 ( 0.986012) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'benchmark' | |
a = (0..10).to_a | |
n = ARGV.first || 1_000_000 | |
Benchmark.bmbm do |b| | |
b.report("nil") { n.times { nil } } | |
b.report("identity") { n.times { a.map {|i| i } } } | |
b.report("block") { n.times { a.map {|i| i.to_i } } } | |
b.report("to_proc") { n.times { a.map(&:to_i) } } | |
b.report("symbol") { n.times { a.map(:to_i) } } | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/array.c b/array.c | |
index 76a3a62..7cdd041 100644 | |
--- a/array.c | |
+++ b/array.c | |
@@ -2530,16 +2530,29 @@ rb_ary_sort_by_bang(VALUE ary) | |
*/ | |
static VALUE | |
-rb_ary_collect(VALUE ary) | |
+rb_ary_collect(int argc, VALUE *argv, VALUE ary) | |
{ | |
long i; | |
- VALUE collect; | |
+ VALUE collect, op; | |
+ ID id; | |
- RETURN_SIZED_ENUMERATOR(ary, 0, 0, rb_ary_length); | |
collect = rb_ary_new2(RARRAY_LEN(ary)); | |
- for (i = 0; i < RARRAY_LEN(ary); i++) { | |
- rb_ary_push(collect, rb_yield(RARRAY_PTR(ary)[i])); | |
+ | |
+ if (rb_scan_args(argc, argv, "01", &op) > 0) { | |
+ id = rb_check_id(&op); | |
+ | |
+ for (i = 0; i < RARRAY_LEN(ary); i++) { | |
+ rb_ary_push(collect, rb_funcall(RARRAY_PTR(ary)[i], id, 0)); | |
+ } | |
} | |
+ else { | |
+ RETURN_SIZED_ENUMERATOR(ary, 0, 0, rb_ary_length); | |
+ | |
+ for (i = 0; i < RARRAY_LEN(ary); i++) { | |
+ rb_ary_push(collect, rb_yield(RARRAY_PTR(ary)[i])); | |
+ } | |
+ } | |
+ | |
return collect; | |
} | |
@@ -5493,9 +5506,9 @@ Init_Array(void) | |
rb_define_method(rb_cArray, "sort", rb_ary_sort, 0); | |
rb_define_method(rb_cArray, "sort!", rb_ary_sort_bang, 0); | |
rb_define_method(rb_cArray, "sort_by!", rb_ary_sort_by_bang, 0); | |
- rb_define_method(rb_cArray, "collect", rb_ary_collect, 0); | |
+ rb_define_method(rb_cArray, "collect", rb_ary_collect, -1); | |
rb_define_method(rb_cArray, "collect!", rb_ary_collect_bang, 0); | |
- rb_define_method(rb_cArray, "map", rb_ary_collect, 0); | |
+ rb_define_method(rb_cArray, "map", rb_ary_collect, -1); | |
rb_define_method(rb_cArray, "map!", rb_ary_collect_bang, 0); | |
rb_define_method(rb_cArray, "select", rb_ary_select, 0); | |
rb_define_method(rb_cArray, "select!", rb_ary_select_bang, 0); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment