Project

General

Profile

Feature #14550 ยป date-step-2.patch

ksss (Yuki Kurihara), 02/25/2018 08:35 AM

View differences:

ext/date/date_core.c
20 20

  
21 21
#define USE_PACK
22 22

  
23
static ID id_cmp, id_le_p, id_ge_p, id_eqeq_p;
23
static ID id_cmp, id_le_p, id_ge_p, id_eqeq_p, id_to, id_by;
24 24
static VALUE cDate, cDateTime;
25 25
static VALUE half_days_in_day, day_in_nanoseconds;
26 26
static double positive_inf, negative_inf;
......
6141 6141

  
6142 6142
/*
6143 6143
 * call-seq:
6144
 *    d.step(limit[, step=1])              ->  enumerator
6145
 *    d.step(limit[, step=1]){|date| ...}  ->  self
6144
 *    d.step(limit[, step=1])                  ->  enumerator
6145
 *    d.step(limit[, step=1]){|date| ...}      ->  self
6146
 *    d.step(to: limit, by: step)              ->  enumerator
6147
 *    d.step(to: limit, by: step) {|date| ...} ->  self
6146 6148
 *
6147 6149
 * Iterates evaluation of the given block, which takes a date object.
6148 6150
 * The limit should be a date object.
6149 6151
 *
6150 6152
 *    Date.new(2001).step(Date.new(2001,-1,-1)).select{|d| d.sunday?}.size
6151 6153
 *				#=> 52
6154
 *    Date.new(2001, 1, 1).step(to: Date.new(2001,-1,-1), by: 5).count
6155
 *				#=> 73
6152 6156
 */
6153 6157
static VALUE
6154 6158
d_lite_step(int argc, VALUE *argv, VALUE self)
6155 6159
{
6156
    VALUE limit, step, date;
6160
    VALUE limit, step, hash, date;
6157 6161

  
6158
    rb_scan_args(argc, argv, "11", &limit, &step);
6162
    RETURN_ENUMERATOR(self, argc, argv);
6159 6163

  
6160
    if (argc < 2)
6164
    argc = rb_scan_args(argc, argv, "02:", &limit, &step, &hash);
6165

  
6166
    if (!NIL_P(hash)) {
6167
	ID keys[2];
6168
	VALUE values[2];
6169
	keys[0] = id_to;
6170
	keys[1] = id_by;
6171
	rb_get_kwargs(hash, keys, 0, 2, values);
6172
	if (values[0] != Qundef) {
6173
	    if (argc > 0) rb_raise(rb_eArgError, "to is given twice");
6174
	    limit = values[0];
6175
	}
6176
	if (values[1] != Qundef) {
6177
	    if (argc > 1) rb_raise(rb_eArgError, "step is given twice");
6178
	    step = values[1];
6179
	}
6180
    }
6181

  
6182
    if (NIL_P(step)) {
6161 6183
	step = INT2FIX(1);
6184
    }
6162 6185

  
6163 6186
#if 0
6164 6187
    if (f_zero_p(step))
6165 6188
	rb_raise(rb_eArgError, "step can't be 0");
6166 6189
#endif
6167 6190

  
6168
    RETURN_ENUMERATOR(self, argc, argv);
6169

  
6170 6191
    date = self;
6171 6192
    switch (FIX2INT(f_cmp(step, INT2FIX(0)))) {
6172 6193
      case -1:
......
9664 9685
			       date_s_test_unit_conv, 0);
9665 9686
    de_define_singleton_method(cDate, "test_all", date_s_test_all, 0);
9666 9687
#endif
9688

  
9689
    id_to = rb_intern("to");
9690
    id_by = rb_intern("by");
9667 9691
}
9668 9692

  
9669 9693
/*
test/date/test_date_arith.rb
245 245
    end
246 246
    assert_equal(4, i)
247 247

  
248
    i = 0
249
    p.step(q, by: 2) do
250
      i += 1
251
    end
252
    assert_equal(4, i)
253

  
254
    i = 0
255
    p.step(to: q, by: 2) do
256
      i += 1
257
    end
258
    assert_equal(4, i)
259

  
248 260
    i = 0
249 261
    p.step(q) do
250 262
      i += 1
251 263
    end
252 264
    assert_equal(8, i)
265

  
266
    i = 0
267
    p.step(to: q) do
268
      i += 1
269
    end
270
    assert_equal(8, i)
271

  
272
    assert_raise(ArgumentError) { p.step(q, to: q) { } }
273
    assert_raise(ArgumentError) { p.step(q, 1, by: 1) { } }
274
    assert_raise(ArgumentError) { p.step(q, foo: nil) { } }
253 275
  end
254 276

  
255 277
  def test_step__noblock
256 278
    p = Date.new(2001,1,14)
257 279
    q = Date.new(2001,1,21)
280

  
258 281
    e = p.step(q, 2)
259 282
    assert_equal(4, e.to_a.size)
260 283

  
284
    e = p.step(q, by: 2)
285
    assert_equal(4, e.to_a.size)
286

  
287
    e = p.step(to: q, by: 2)
288
    assert_equal(4, e.to_a.size)
289

  
261 290
    e = p.step(q)
262 291
    assert_equal(8, e.to_a.size)
292

  
293
    e = p.step(to: q)
294
    assert_equal(8, e.to_a.size)
263 295
  end
264 296

  
265 297
end