Project

General

Profile

patch2.diff

Glass_saga (Masaki Matsushita), 07/29/2013 12:24 PM

View differences:

hash.c
1085 1085
    return rb_hash_delete_if(rb_obj_dup(hash));
1086 1086
}
1087 1087

  
1088
struct slice_i_arg {
1089
    int argc;
1090
    VALUE *argv;
1091
    VALUE result;
1092
};
1093

  
1094
static int
1095
slice_i(VALUE key, VALUE value, VALUE arg)
1096
{
1097
    int i;
1098
    struct slice_i_arg *p = (struct slice_i_arg *)arg;
1099
    VALUE key_to_slice;
1100

  
1101
    for (i = 0; i < p->argc; i++) {
1102
	key_to_slice = p->argv[i];
1103
	if (rb_equal(key, key_to_slice))
1104
	    return ST_CONTINUE;
1105
    }
1106

  
1107
    rb_hash_aset(p->result, key, value);
1108
    return ST_DELETE;
1109
}
1110

  
1111
static VALUE
1112
rb_hash_slice_bang(int argc, VALUE *argv, VALUE hash)
1113
{
1114
    st_index_t n;
1115
    VALUE result;
1116

  
1117
    rb_hash_modify(hash);
1118
    n = RHASH_SIZE(hash);
1119
    if (!n) return hash;
1120
    if (argc) {
1121
	struct slice_i_arg arg;
1122
	result = rb_hash_new();
1123
	arg.argc = argc;
1124
	arg.argv = argv;
1125
	arg.result = result;
1126
	rb_hash_foreach(hash, slice_i, (VALUE)&arg);
1127
    }
1128
    else {
1129
	result = rb_obj_dup(hash);
1130
	rb_hash_clear(hash);
1131
    }
1132

  
1133
    return result;
1134
}
1135

  
1136
static VALUE
1137
rb_hash_slice(int argc, VALUE *argv, VALUE hash)
1138
{
1139
    int i;
1140
    VALUE key, value, result = rb_hash_new();
1141

  
1142
    if (!argc || RHASH_EMPTY_P(hash)) return result;
1143

  
1144
    for (i = 0; i < argc; i++) {
1145
	key = argv[i];
1146
	value = rb_hash_lookup2(hash, key, Qundef);
1147
	if (value != Qundef)
1148
	    rb_hash_aset(result, key, value);
1149
    }
1150

  
1151
    return result;
1152
}
1153

  
1154
struct except_i_arg {
1155
    int argc;
1156
    VALUE *argv;
1157
};
1158

  
1159
static int
1160
except_i(VALUE key, VALUE value, VALUE arg)
1161
{
1162
    int i;
1163
    struct except_i_arg *p = (struct except_i_arg *)arg;
1164
    VALUE key_to_except;
1165

  
1166
    for (i = 0; i < p->argc; i++) {
1167
	key_to_except = p->argv[i];
1168
	if (rb_equal(key, key_to_except))
1169
	    return ST_DELETE;
1170
    }
1171

  
1172
    return ST_CONTINUE;
1173
}
1174

  
1175
static VALUE
1176
rb_hash_except_bang(int argc, VALUE *argv, VALUE hash)
1177
{
1178
    st_index_t n;
1179
    struct except_i_arg arg;
1180

  
1181
    rb_hash_modify(hash);
1182
    n = RHASH_SIZE(hash);
1183

  
1184
    if (n && argc) {
1185
	arg.argc = argc;
1186
	arg.argv = argv;
1187
	rb_hash_foreach(hash, except_i, (VALUE)&arg);
1188
    }
1189

  
1190
    return hash;
1191
}
1192

  
1193
static VALUE
1194
rb_hash_except(int argc, VALUE *argv, VALUE hash)
1195
{
1196
    VALUE result = rb_obj_dup(hash);
1197
    rb_hash_except_bang(argc, argv, result);
1198
    return result;
1199
}
1200

  
1088 1201
/*
1089 1202
 * call-seq:
1090 1203
 *   hsh.values_at(key, ...)   -> array
......
3597 3710
    rb_define_method(rb_cHash,"select!", rb_hash_select_bang, 0);
3598 3711
    rb_define_method(rb_cHash,"reject", rb_hash_reject, 0);
3599 3712
    rb_define_method(rb_cHash,"reject!", rb_hash_reject_bang, 0);
3713
    rb_define_method(rb_cHash,"slice", rb_hash_slice, -1);
3714
    rb_define_method(rb_cHash,"slice!", rb_hash_slice_bang, -1);
3715
    rb_define_method(rb_cHash,"except", rb_hash_except, -1);
3716
    rb_define_method(rb_cHash,"except!", rb_hash_except_bang, -1);
3600 3717
    rb_define_method(rb_cHash,"clear", rb_hash_clear, 0);
3601 3718
    rb_define_method(rb_cHash,"invert", rb_hash_invert, 0);
3602 3719
    rb_define_method(rb_cHash,"update", rb_hash_update, 1);
test/ruby/test_hash.rb
796 796
    assert_equal(nil, h.select!{true})
797 797
  end
798 798

  
799
  def test_slice
800
    h = {1=>2,3=>4,5=>6}
801
    assert_equal({1=>2, 3=>4}, h.slice(1, 3))
802
    assert_equal({}, h.slice)
803
  end
804

  
805
  def test_slice!
806
    h = {1=>2,3=>4,5=>6}
807
    assert_equal({5=>6}, h.slice!(1, 3))
808
    assert_equal({1=>2,3=>4}, h)
809
    assert_equal({1=>2,3=>4}, h.slice!(7))
810
    assert_equal({}, h)
811
    assert_equal({}, {}.slice!)
812
  end
813

  
814
  def test_except
815
    h = {1=>2,3=>4,5=>6}
816
    assert_equal({5=>6}, h.except(1, 3))
817
    assert_equal(h, h.except)
818
  end
819

  
820
  def test_except!
821
    h = {1=>2,3=>4,5=>6}
822
    assert_equal({5=>6}, h.except!(1, 3))
823
    assert_equal({5=>6}, h)
824
    assert_equal({5=>6}, h.except!(1,3))
825
    assert_equal({5=>6}, h.except!)
826
    assert_equal({5=>6}, h)
827
  end
828

  
799 829
  def test_clear2
800 830
    assert_equal({}, {1=>2,3=>4,5=>6}.clear)
801 831
    h = {1=>2,3=>4,5=>6}