Last active
September 15, 2017 05:47
-
-
Save yalab/fef4eccc0db5da98337a2c3ef92b84bd to your computer and use it in GitHub Desktop.
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/numeric.c b/numeric.c | |
index 480ab7e0cb..bdf885cf57 100644 | |
--- a/numeric.c | |
+++ b/numeric.c | |
@@ -186,7 +186,7 @@ VALUE rb_cFixnum; | |
VALUE rb_eZeroDivError; | |
VALUE rb_eFloatDomainError; | |
-static ID id_to, id_by; | |
+static ID id_to, id_by, id_from; | |
void | |
rb_num_zerodiv(void) | |
@@ -4969,16 +4969,30 @@ int_dotimes_size(VALUE num, VALUE args, VALUE eobj) | |
} | |
static VALUE | |
-int_dotimes(VALUE num) | |
+int_dotimes(int argc, VALUE *argv, VALUE num) | |
{ | |
- RETURN_SIZED_ENUMERATOR(num, 0, 0, int_dotimes_size); | |
+ VALUE hash; | |
+ long from; | |
+ | |
+ RETURN_SIZED_ENUMERATOR(num, argc, argv, int_dotimes_size); | |
+ | |
+ rb_scan_args(argc, argv, ":", &hash); | |
+ if (NIL_P(hash)) { | |
+ from = 0; | |
+ } else { | |
+ ID keys[1]; | |
+ VALUE values[1]; | |
+ keys[0] = id_from; | |
+ rb_get_kwargs(hash, keys, 0, 1, values); | |
+ from = FIX2LONG(values[0]); | |
+ } | |
if (FIXNUM_P(num)) { | |
long i, end; | |
end = FIX2LONG(num); | |
for (i=0; i<end; i++) { | |
- rb_yield_1(LONG2FIX(i)); | |
+ rb_yield_1(LONG2FIX(i + from)); | |
} | |
} | |
else { | |
@@ -5398,7 +5412,7 @@ Init_Numeric(void) | |
rb_define_method(rb_cInteger, "even?", int_even_p, 0); | |
rb_define_method(rb_cInteger, "upto", int_upto, 1); | |
rb_define_method(rb_cInteger, "downto", int_downto, 1); | |
- rb_define_method(rb_cInteger, "times", int_dotimes, 0); | |
+ rb_define_method(rb_cInteger, "times", int_dotimes, -1); | |
rb_define_method(rb_cInteger, "succ", int_succ, 0); | |
rb_define_method(rb_cInteger, "next", int_succ, 0); | |
rb_define_method(rb_cInteger, "pred", int_pred, 0); | |
@@ -5600,6 +5614,7 @@ Init_Numeric(void) | |
id_to = rb_intern("to"); | |
id_by = rb_intern("by"); | |
+ id_from = rb_intern("from"); | |
} | |
#undef rb_float_value | |
diff --git a/spec/rubyspec/core/integer/times_spec.rb b/spec/rubyspec/core/integer/times_spec.rb | |
index d426bc008c..b67455b2f2 100644 | |
--- a/spec/rubyspec/core/integer/times_spec.rb | |
+++ b/spec/rubyspec/core/integer/times_spec.rb | |
@@ -65,6 +65,20 @@ | |
result.should == [0, 1, 2] | |
end | |
+ it "use from keyword argument for initial value" do | |
+ result = [] | |
+ | |
+ 3.times(from: 1) do |i| | |
+ result << i | |
+ end | |
+ | |
+ result.should == [1, 2, 3] | |
+ end | |
+ | |
+ it "use from keyword argument as Enumerator" do | |
+ 3.times(from: 1).to_a.should == [1, 2, 3] | |
+ end | |
+ | |
describe "when no block is given" do | |
describe "returned Enumerator" do | |
describe "size" do |
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
$ ./configure optflags="-O0" debugflags="-g3" | |
$ make | |
$ lldb ./ruby | |
(lldb) breakpoint set --name int_dotimes | |
(lldb) r --disable=gems -e '10.times(from: 1){\|n\| n }' | |
(lldb) call rb_p(num) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment