Skip to content

Instantly share code, notes, and snippets.

@phiggins
Last active December 15, 2015 20:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phiggins/5317981 to your computer and use it in GitHub Desktop.
Save phiggins/5317981 to your computer and use it in GitHub Desktop.
Patch to allow Ruby's Array#map to take a symbol.
$ ./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)
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
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