methodmissing-hwia 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bench/bench.rb +16 -4
- data/ext/hwia/hwia.c +117 -143
- data/hwia.gemspec +1 -1
- metadata +1 -1
data/bench/bench.rb
CHANGED
@@ -3,16 +3,20 @@ $:.unshift "." #ruby 1.9.2
|
|
3
3
|
require File.dirname(__FILE__) + "/../ext/hwia/hwia"
|
4
4
|
require File.dirname(__FILE__) + "/as_hwia"
|
5
5
|
|
6
|
-
STR_HASH = { :a => 1, 'b' => 2 }.strhash
|
7
|
-
HWIA_HASH = HashWithIndifferentAccess.new({ :a => 1, 'b' => 2 })
|
6
|
+
STR_HASH = { :a => 1, 'b' => 2, 1 => 1, [1] => 1 }.strhash
|
7
|
+
HWIA_HASH = HashWithIndifferentAccess.new({ :a => 1, 'b' => 2, 1 => 1, [1] => 1 })
|
8
8
|
HASH = { :d => :d, 'e' => :e }
|
9
9
|
|
10
10
|
TESTS = 10_000
|
11
11
|
Benchmark.bmbm do |results|
|
12
|
-
results.report("StrHash#[:sym]") { TESTS.times { STR_HASH[:
|
13
|
-
results.report("HashWithIndifferentAccess#[:sym]") { TESTS.times { HWIA_HASH[:a] } }
|
12
|
+
results.report("StrHash#[:sym]") { TESTS.times { STR_HASH[:sym] } }
|
13
|
+
results.report("HashWithIndifferentAccess#[:sym]") { TESTS.times { HWIA_HASH[:a] } }
|
14
14
|
results.report("StrHash#['str']") { TESTS.times { STR_HASH['b'] } }
|
15
15
|
results.report("HashWithIndifferentAccess#['str]") { TESTS.times { HWIA_HASH['b'] } }
|
16
|
+
results.report("StrHash#[1]") { TESTS.times { STR_HASH[1] } }
|
17
|
+
results.report("HashWithIndifferentAccess#[1]") { TESTS.times { HWIA_HASH[1] } }
|
18
|
+
results.report("StrHash#[[1]]") { TESTS.times { STR_HASH[[1]] } }
|
19
|
+
results.report("HashWithIndifferentAccess#[[1]]") { TESTS.times { HWIA_HASH[[1]] } }
|
16
20
|
results.report("StrHash#key?(:sym)") { TESTS.times { STR_HASH.key?(:a) } }
|
17
21
|
results.report("HashWithIndifferentAccess#key?(:sym)") { TESTS.times { HWIA_HASH.key?(:a) } }
|
18
22
|
results.report("StrHash#key?('str')") { TESTS.times { STR_HASH.key?('a') } }
|
@@ -29,6 +33,10 @@ Benchmark.bmbm do |results|
|
|
29
33
|
results.report("HashWithIndifferentAccess#['str]=") { TESTS.times { HWIA_HASH['c'] = :c } }
|
30
34
|
results.report("StrHash#[:sym]=") { TESTS.times { STR_HASH[:c] = :c } }
|
31
35
|
results.report("HashWithIndifferentAccess#[:sym]=") { TESTS.times { HWIA_HASH[:c] = :c } }
|
36
|
+
results.report("StrHash#[2]=") { TESTS.times { STR_HASH[2] = 2 } }
|
37
|
+
results.report("HashWithIndifferentAccess#[2]=") { TESTS.times { HWIA_HASH[2] = 2 } }
|
38
|
+
results.report("StrHash#[[2]]=") { TESTS.times { STR_HASH[[2]] = 2 } }
|
39
|
+
results.report("HashWithIndifferentAccess#[[2]]=") { TESTS.times { HWIA_HASH[[2]] = 2 } }
|
32
40
|
results.report("StrHash#update") { TESTS.times { STR_HASH.update(HASH) } }
|
33
41
|
results.report("HashWithIndifferentAccess#update") { TESTS.times { HWIA_HASH.update(HASH) } }
|
34
42
|
results.report("StrHash#dup") { TESTS.times { STR_HASH.dup } }
|
@@ -37,4 +45,8 @@ Benchmark.bmbm do |results|
|
|
37
45
|
results.report("HashWithIndifferentAccess#merge") { TESTS.times { HWIA_HASH.merge(HASH) } }
|
38
46
|
results.report("StrHash#to_hash") { TESTS.times { STR_HASH.to_hash } }
|
39
47
|
results.report("HashWithIndifferentAccess#to_hash") { TESTS.times { HWIA_HASH.to_hash } }
|
48
|
+
results.report("StrHash#keys") { TESTS.times { STR_HASH.keys } }
|
49
|
+
results.report("HashWithIndifferentAccess#keys") { TESTS.times { HWIA_HASH.keys } }
|
50
|
+
results.report("StrHash#values") { TESTS.times { STR_HASH.values } }
|
51
|
+
results.report("HashWithIndifferentAccess#values") { TESTS.times { HWIA_HASH.values } }
|
40
52
|
end
|
data/ext/hwia/hwia.c
CHANGED
@@ -38,44 +38,44 @@ strhash(register const char *string)
|
|
38
38
|
register int c;
|
39
39
|
register int val = 0;
|
40
40
|
while ((c = *string++) != '\0') {
|
41
|
-
|
41
|
+
val = val*997 + c;
|
42
42
|
}
|
43
43
|
return val + (val>>5);
|
44
44
|
}
|
45
45
|
|
46
46
|
int
|
47
|
-
rb_sym_strhash(VALUE sym)
|
47
|
+
rb_sym_strhash(VALUE *sym)
|
48
48
|
{
|
49
|
-
|
49
|
+
ID id = SYM2ID(*sym);
|
50
50
|
return strhash((char*)rb_id2name(id));
|
51
51
|
}
|
52
52
|
|
53
53
|
static VALUE
|
54
54
|
rb_sym_strhash_m(VALUE sym)
|
55
55
|
{
|
56
|
-
return INT2FIX(rb_sym_strhash(sym));
|
56
|
+
return INT2FIX(rb_sym_strhash(&sym));
|
57
57
|
}
|
58
58
|
|
59
59
|
int
|
60
|
-
rb_str_strhash(VALUE str)
|
60
|
+
rb_str_strhash(VALUE *str)
|
61
61
|
{
|
62
|
-
return strhash((char*)RSTRING_PTR(str));
|
62
|
+
return strhash((char*)RSTRING_PTR(*str));
|
63
63
|
}
|
64
64
|
|
65
65
|
static VALUE
|
66
66
|
rb_str_strhash_m(VALUE str)
|
67
67
|
{
|
68
|
-
return INT2FIX(rb_str_strhash(str));
|
68
|
+
return INT2FIX(rb_str_strhash(&str));
|
69
69
|
}
|
70
70
|
|
71
71
|
int
|
72
|
-
rb_strhash_cmp(VALUE s1,VALUE s2)
|
72
|
+
rb_strhash_cmp(VALUE *s1,VALUE *s2)
|
73
73
|
{
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
74
|
+
int s1_hash = SYMBOL_P(*s1) ? rb_sym_strhash(s1) : rb_str_strhash(s1);
|
75
|
+
int s2_hash = SYMBOL_P(*s2) ? rb_sym_strhash(s2) : rb_str_strhash(s2);
|
76
|
+
if (s1_hash == s2_hash) return 0;
|
77
|
+
if (s1_hash > s2_hash) return 1;
|
78
|
+
return -1;
|
79
79
|
}
|
80
80
|
|
81
81
|
/* hash.c */
|
@@ -85,7 +85,7 @@ rb_hash_has_key(hash, key)
|
|
85
85
|
VALUE key;
|
86
86
|
{
|
87
87
|
#ifdef RUBY19
|
88
|
-
if (!
|
88
|
+
if (!HASH_TBL(hash))
|
89
89
|
return Qfalse;
|
90
90
|
#endif
|
91
91
|
if (st_lookup(HASH_TBL(hash), key, 0)) {
|
@@ -111,19 +111,15 @@ rb_strhash_hash_cmp(VALUE a, VALUE b)
|
|
111
111
|
VALUE args[2];
|
112
112
|
#endif
|
113
113
|
if (a == b) return 0;
|
114
|
-
if (FIXNUM_P(a) && FIXNUM_P(b))
|
115
|
-
|
114
|
+
if (FIXNUM_P(a) && FIXNUM_P(b)) return a != b;
|
115
|
+
if (a == Qundef || b == Qundef) return -1;
|
116
|
+
if (SYMBOL_P(a) && SYMBOL_P(b)) return a != b;
|
117
|
+
if ((TYPE(a) == T_STRING && RBASIC(a)->klass == rb_cString && SYMBOL_P(b)) || (TYPE(b) == T_STRING && RBASIC(b)->klass == rb_cString && SYMBOL_P(a))) {
|
118
|
+
return rb_strhash_cmp(&a, &b);
|
116
119
|
}
|
117
120
|
if (TYPE(a) == T_STRING && RBASIC(a)->klass == rb_cString &&
|
118
|
-
|
119
|
-
|
120
|
-
}
|
121
|
-
if (SYMBOL_P(b) && (TYPE(a) == T_STRING && RBASIC(a)->klass == rb_cString) || (SYMBOL_P(a) && TYPE(b) == T_STRING && RBASIC(b)->klass == rb_cString)) {
|
122
|
-
return rb_strhash_cmp(a, b);
|
123
|
-
}
|
124
|
-
if (a == Qundef || b == Qundef) return -1;
|
125
|
-
if (SYMBOL_P(a) && SYMBOL_P(b)) {
|
126
|
-
return a != b;
|
121
|
+
TYPE(b) == T_STRING && RBASIC(b)->klass == rb_cString) {
|
122
|
+
return rb_str_cmp(a, b);
|
127
123
|
}
|
128
124
|
#ifdef RUBY18
|
129
125
|
args[0] = a;
|
@@ -134,62 +130,42 @@ rb_strhash_hash_cmp(VALUE a, VALUE b)
|
|
134
130
|
#endif
|
135
131
|
}
|
136
132
|
|
137
|
-
VALUE
|
138
|
-
rb_strhash(VALUE obj)
|
139
|
-
{
|
140
|
-
VALUE hval = rb_funcall(obj, id_hash, 0);
|
141
|
-
#ifdef RUBY18
|
142
|
-
return hval;
|
143
|
-
#else
|
144
|
-
retry:
|
145
|
-
switch (TYPE(hval)) {
|
146
|
-
case T_FIXNUM:
|
147
|
-
return hval;
|
148
|
-
|
149
|
-
case T_BIGNUM:
|
150
|
-
return LONG2FIX(((long*)(RBIGNUM_DIGITS(hval)))[0]);
|
151
|
-
|
152
|
-
default:
|
153
|
-
hval = rb_to_int(hval);
|
154
|
-
goto retry;
|
155
|
-
}
|
156
|
-
#endif
|
157
|
-
}
|
158
|
-
|
159
133
|
/* hash.c */
|
160
134
|
static int
|
161
135
|
rb_strhash_hash(VALUE a)
|
162
136
|
{
|
163
|
-
VALUE hval
|
137
|
+
VALUE hval;
|
138
|
+
int hnum;
|
139
|
+
|
164
140
|
switch (TYPE(a)) {
|
165
141
|
case T_FIXNUM:
|
166
142
|
#ifdef RUBY18
|
167
143
|
return (int)a;
|
168
144
|
#else
|
169
|
-
hnum = a;
|
170
|
-
|
145
|
+
hnum = (int)a;
|
146
|
+
break;
|
171
147
|
#endif
|
172
148
|
case T_SYMBOL:
|
173
|
-
|
174
|
-
|
149
|
+
hnum = rb_sym_strhash(&a);
|
150
|
+
break;
|
175
151
|
case T_STRING:
|
176
|
-
|
177
|
-
|
152
|
+
hnum = rb_str_strhash(&a);
|
153
|
+
break;
|
178
154
|
|
179
155
|
default:
|
180
|
-
|
156
|
+
hval = rb_hash(a);
|
181
157
|
#ifdef RUBY18
|
182
|
-
|
183
|
-
|
184
|
-
|
158
|
+
if (!FIXNUM_P(hval)) {
|
159
|
+
hval = rb_funcall(hval, '%', 1, hash_format);
|
160
|
+
}
|
185
161
|
#endif
|
186
|
-
|
162
|
+
hnum = (int)hval;
|
187
163
|
}
|
188
164
|
#ifdef RUBY18
|
189
|
-
return
|
165
|
+
return hnum;
|
190
166
|
#else
|
191
167
|
hnum <<= 1;
|
192
|
-
return
|
168
|
+
return RSHIFT(hnum, 1);
|
193
169
|
#endif
|
194
170
|
}
|
195
171
|
|
@@ -199,10 +175,10 @@ static struct st_hash_type objstrhash = {
|
|
199
175
|
};
|
200
176
|
|
201
177
|
static void
|
202
|
-
rb_hash_modify_check(VALUE hash){
|
203
|
-
if (OBJ_FROZEN(hash)) rb_error_frozen("hash");
|
204
|
-
if (!OBJ_TAINTED(hash) && rb_safe_level() >= 4)
|
205
|
-
|
178
|
+
rb_hash_modify_check(VALUE *hash){
|
179
|
+
if (OBJ_FROZEN(*hash)) rb_error_frozen("hash");
|
180
|
+
if (!OBJ_TAINTED(*hash) && rb_safe_level() >= 4)
|
181
|
+
rb_raise(rb_eSecurityError, "Insecure: can't modify hash");
|
206
182
|
}
|
207
183
|
|
208
184
|
/* hash.c */
|
@@ -212,20 +188,20 @@ rb_hash_modify(VALUE hash)
|
|
212
188
|
#ifdef RUBY18
|
213
189
|
if (!HASH_TBL(hash)) rb_raise(rb_eTypeError, "uninitialized Hash");
|
214
190
|
#endif
|
215
|
-
|
191
|
+
rb_hash_modify_check(&hash);
|
216
192
|
#ifdef RUBY19
|
217
193
|
if (!HASH_TBL(hash)) HASH_TBL(hash) = st_init_table(&objstrhash);
|
218
194
|
#endif
|
219
195
|
}
|
220
196
|
|
221
|
-
static VALUE strhash_alloc0 _((VALUE));
|
197
|
+
static VALUE strhash_alloc0 _((VALUE*));
|
222
198
|
static VALUE strhash_alloc _((VALUE));
|
223
199
|
/* hash.c */
|
224
200
|
static VALUE
|
225
|
-
strhash_alloc0(VALUE klass)
|
201
|
+
strhash_alloc0(VALUE *klass)
|
226
202
|
{
|
227
203
|
NEWOBJ(hash, struct RHash);
|
228
|
-
OBJSETUP(hash, klass, T_HASH);
|
204
|
+
OBJSETUP(hash, *klass, T_HASH);
|
229
205
|
|
230
206
|
hash->ifnone = Qnil;
|
231
207
|
|
@@ -235,27 +211,24 @@ strhash_alloc0(VALUE klass)
|
|
235
211
|
static VALUE
|
236
212
|
strhash_alloc(VALUE klass)
|
237
213
|
{
|
238
|
-
VALUE hash = strhash_alloc0(klass);
|
214
|
+
VALUE hash = strhash_alloc0(&klass);
|
239
215
|
|
240
216
|
HASH_TBL(hash) = st_init_table(&objstrhash);
|
241
217
|
|
242
218
|
return hash;
|
243
219
|
}
|
244
220
|
|
245
|
-
VALUE
|
246
|
-
rb_strhash_new()
|
247
|
-
{
|
248
|
-
return strhash_alloc(rb_cStrHash);
|
249
|
-
}
|
250
|
-
|
251
221
|
static VALUE rb_hash_strhash(VALUE hash);
|
252
|
-
static
|
222
|
+
static void rb_strhash_convert(VALUE *value);
|
253
223
|
|
254
224
|
/* hash.c */
|
255
225
|
static int
|
256
226
|
rb_hash_rehash_i(VALUE key, VALUE value, st_table *tbl)
|
257
227
|
{
|
258
|
-
if (key != Qundef)
|
228
|
+
if (key != Qundef){
|
229
|
+
rb_strhash_convert(&value);
|
230
|
+
st_insert(tbl, key, value);
|
231
|
+
}
|
259
232
|
return ST_CONTINUE;
|
260
233
|
}
|
261
234
|
|
@@ -266,9 +239,9 @@ rb_strhash_rehash(VALUE hash)
|
|
266
239
|
st_table *tbl;
|
267
240
|
#ifdef RUBY19
|
268
241
|
if (RHASH(hash)->iter_lev > 0) {
|
269
|
-
|
242
|
+
rb_raise(rb_eRuntimeError, "rehash during iteration");
|
270
243
|
}
|
271
|
-
rb_hash_modify_check(hash);
|
244
|
+
rb_hash_modify_check(&hash);
|
272
245
|
if (!RHASH(hash)->ntbl)
|
273
246
|
return hash;
|
274
247
|
#endif
|
@@ -281,33 +254,32 @@ rb_strhash_rehash(VALUE hash)
|
|
281
254
|
return hash;
|
282
255
|
}
|
283
256
|
|
284
|
-
|
285
|
-
|
286
|
-
rb_strhash_convert(VALUE hash, VALUE val)
|
257
|
+
static void
|
258
|
+
rb_strhash_convert(VALUE *val)
|
287
259
|
{
|
288
260
|
int i;
|
289
261
|
VALUE values;
|
290
262
|
|
291
|
-
switch (TYPE(val)) {
|
263
|
+
switch (TYPE(*val)) {
|
292
264
|
case T_HASH:
|
293
|
-
|
265
|
+
*val = rb_hash_strhash(*val);
|
266
|
+
break;
|
294
267
|
case T_ARRAY:
|
295
|
-
values = rb_ary_new2(RARRAY_LEN(val));
|
296
|
-
for (i = 0; i < RARRAY_LEN(val); i++) {
|
297
|
-
VALUE el = RARRAY_PTR(val)[i];
|
268
|
+
values = rb_ary_new2(RARRAY_LEN(*val));
|
269
|
+
for (i = 0; i < RARRAY_LEN(*val); i++) {
|
270
|
+
VALUE el = RARRAY_PTR(*val)[i];
|
298
271
|
rb_ary_push(values, (TYPE(el) == T_HASH) ? rb_hash_strhash(el) : el);
|
299
272
|
}
|
300
|
-
|
301
|
-
|
302
|
-
return val;
|
273
|
+
*val = values;
|
274
|
+
break;
|
303
275
|
}
|
304
276
|
}
|
305
277
|
|
306
278
|
static VALUE
|
307
279
|
rb_strhash_aset(VALUE hash, VALUE key, VALUE val){
|
308
|
-
|
309
|
-
|
310
|
-
return
|
280
|
+
rb_strhash_convert(&val);
|
281
|
+
rb_hash_aset(hash, key, val);
|
282
|
+
return val;
|
311
283
|
}
|
312
284
|
|
313
285
|
/* hash.c */
|
@@ -318,15 +290,15 @@ rb_strhash_s_create(int argc, VALUE *argv, VALUE klass)
|
|
318
290
|
int i;
|
319
291
|
|
320
292
|
if (argc == 1 && TYPE(argv[0]) == T_HASH) {
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
293
|
+
hash = strhash_alloc0(&klass);
|
294
|
+
HASH_TBL(hash) = st_copy(HASH_TBL(argv[0]));
|
295
|
+
HASH_TBL(hash)->type = &objstrhash;
|
296
|
+
RHASH(hash)->ifnone = RHASH(argv[0])->ifnone;
|
297
|
+
return rb_strhash_rehash(hash);
|
326
298
|
}
|
327
299
|
|
328
300
|
if (argc % 2 != 0) {
|
329
|
-
|
301
|
+
rb_raise(rb_eArgError, "odd number of arguments for Hash");
|
330
302
|
}
|
331
303
|
|
332
304
|
hash = strhash_alloc(klass);
|
@@ -340,15 +312,15 @@ rb_strhash_s_create(int argc, VALUE *argv, VALUE klass)
|
|
340
312
|
static VALUE
|
341
313
|
rb_strhash_strhash(VALUE hash)
|
342
314
|
{
|
343
|
-
|
315
|
+
return hash;
|
344
316
|
}
|
345
317
|
|
346
318
|
static VALUE
|
347
319
|
rb_hash_strhash(VALUE hash)
|
348
320
|
{
|
349
|
-
|
350
|
-
|
351
|
-
|
321
|
+
VALUE args[1];
|
322
|
+
args[0] = hash;
|
323
|
+
return rb_strhash_s_create(1, (VALUE *)args, rb_cStrHash);
|
352
324
|
}
|
353
325
|
|
354
326
|
/* hash.c */
|
@@ -361,22 +333,24 @@ to_strhash(hash)
|
|
361
333
|
|
362
334
|
/* hash.c */
|
363
335
|
static int
|
364
|
-
rb_strhash_update_i(VALUE key, VALUE value, VALUE hash)
|
336
|
+
rb_strhash_update_i(VALUE key, VALUE value, VALUE *hash)
|
365
337
|
{
|
366
338
|
if (key == Qundef) return ST_CONTINUE;
|
367
|
-
|
339
|
+
rb_strhash_convert(&value);
|
340
|
+
st_insert(HASH_TBL(*hash), key, value);
|
368
341
|
return ST_CONTINUE;
|
369
342
|
}
|
370
343
|
|
371
344
|
/* hash.c */
|
372
345
|
static int
|
373
|
-
rb_strhash_update_block_i(VALUE key, VALUE value, VALUE hash)
|
346
|
+
rb_strhash_update_block_i(VALUE key, VALUE value, VALUE *hash)
|
374
347
|
{
|
375
348
|
if (key == Qundef) return ST_CONTINUE;
|
376
|
-
if (rb_hash_has_key(hash, key)) {
|
377
|
-
|
349
|
+
if (rb_hash_has_key(*hash, key)) {
|
350
|
+
value = rb_yield_values(3, key, rb_hash_aref(*hash, key), value);
|
378
351
|
}
|
379
|
-
|
352
|
+
rb_strhash_convert(&value);
|
353
|
+
st_insert(HASH_TBL(*hash), key, value);
|
380
354
|
return ST_CONTINUE;
|
381
355
|
}
|
382
356
|
|
@@ -385,34 +359,33 @@ static VALUE
|
|
385
359
|
rb_strhash_update(VALUE hash1, VALUE hash2)
|
386
360
|
{
|
387
361
|
#ifdef RUBY19
|
388
|
-
|
362
|
+
rb_hash_modify(hash1);
|
389
363
|
#endif
|
390
364
|
hash2 = to_strhash(hash2);
|
391
365
|
if (rb_block_given_p()) {
|
392
|
-
|
366
|
+
rb_hash_foreach(hash2, rb_strhash_update_block_i, &hash1);
|
393
367
|
}
|
394
368
|
else {
|
395
|
-
|
369
|
+
rb_hash_foreach(hash2, rb_strhash_update_i, &hash1);
|
396
370
|
}
|
397
371
|
return hash1;
|
398
372
|
}
|
399
373
|
|
400
374
|
static VALUE
|
401
375
|
rb_strhash_initialize(int argc, VALUE *argv, VALUE hash){
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
376
|
+
VALUE constructor;
|
377
|
+
rb_scan_args(argc, argv, "01", &constructor);
|
378
|
+
if(TYPE(constructor) == T_HASH){
|
379
|
+
return rb_strhash_update(hash,constructor);
|
380
|
+
}else{
|
381
|
+
return rb_call_super(argc,argv);
|
382
|
+
}
|
409
383
|
}
|
410
384
|
|
411
385
|
static VALUE
|
412
386
|
rb_strhash_merge(VALUE hash1, VALUE hash2){
|
413
|
-
|
414
|
-
|
415
|
-
return rb_strhash_update(hash1,hash2);
|
387
|
+
/* see note in Init */
|
388
|
+
return rb_strhash_update(hash1,hash2);
|
416
389
|
}
|
417
390
|
|
418
391
|
/*hash.c, see rb_strhash_to_hash*/
|
@@ -427,13 +400,13 @@ to_hash(hash)
|
|
427
400
|
static int
|
428
401
|
rb_hash_update_i(key, value, hash)
|
429
402
|
VALUE key, value;
|
430
|
-
VALUE hash;
|
403
|
+
VALUE *hash;
|
431
404
|
{
|
432
405
|
if (key == Qundef) return ST_CONTINUE;
|
433
406
|
#ifdef RUBY19
|
434
|
-
st_insert(RHASH(hash)->ntbl, key, value);
|
407
|
+
st_insert(RHASH(*hash)->ntbl, key, value);
|
435
408
|
#else
|
436
|
-
rb_hash_aset(hash, key, value);
|
409
|
+
rb_hash_aset(*hash, key, value);
|
437
410
|
#endif
|
438
411
|
return ST_CONTINUE;
|
439
412
|
}
|
@@ -442,16 +415,16 @@ rb_hash_update_i(key, value, hash)
|
|
442
415
|
static int
|
443
416
|
rb_hash_update_block_i(key, value, hash)
|
444
417
|
VALUE key, value;
|
445
|
-
VALUE hash;
|
418
|
+
VALUE *hash;
|
446
419
|
{
|
447
420
|
if (key == Qundef) return ST_CONTINUE;
|
448
|
-
if (rb_hash_has_key(hash, key)) {
|
449
|
-
|
421
|
+
if (rb_hash_has_key(*hash, key)) {
|
422
|
+
value = rb_yield_values(3, key, rb_hash_aref(*hash, key), value);
|
450
423
|
}
|
451
424
|
#ifdef RUBY19
|
452
|
-
st_insert(RHASH(hash)->ntbl, key, value);
|
425
|
+
st_insert(RHASH(*hash)->ntbl, key, value);
|
453
426
|
#else
|
454
|
-
rb_hash_aset(hash, key, value);
|
427
|
+
rb_hash_aset(*hash, key, value);
|
455
428
|
#endif
|
456
429
|
return ST_CONTINUE;
|
457
430
|
}
|
@@ -466,29 +439,31 @@ rb_hash_update(hash1, hash2)
|
|
466
439
|
#endif
|
467
440
|
hash2 = to_hash(hash2);
|
468
441
|
if (rb_block_given_p()) {
|
469
|
-
|
442
|
+
rb_hash_foreach(hash2, rb_hash_update_block_i, &hash1);
|
470
443
|
}
|
471
444
|
else {
|
472
|
-
|
445
|
+
rb_hash_foreach(hash2, rb_hash_update_i, &hash1);
|
473
446
|
}
|
474
447
|
return hash1;
|
475
448
|
}
|
476
449
|
|
477
450
|
static int
|
478
|
-
rb_strhash_to_hash_i(VALUE key, VALUE value, VALUE hash){
|
451
|
+
rb_strhash_to_hash_i(VALUE key, VALUE value, VALUE *hash){
|
479
452
|
if (SYMBOL_P(key)){
|
480
|
-
rb_hash_delete(hash,key);
|
481
|
-
|
453
|
+
rb_hash_delete(*hash,key);
|
454
|
+
VALUE str = rb_str_new2(rb_id2name(SYM2ID(key)));
|
455
|
+
OBJ_FREEZE(str);
|
456
|
+
rb_hash_aset(*hash, str, value);
|
482
457
|
}
|
483
458
|
return ST_CONTINUE;
|
484
459
|
}
|
485
460
|
|
486
461
|
static VALUE
|
487
462
|
rb_strhash_to_hash(VALUE hash){
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
463
|
+
VALUE hsh = rb_hash_update(rb_hash_new(), hash);
|
464
|
+
RHASH(hsh)->ifnone = RHASH(hash)->ifnone;
|
465
|
+
rb_hash_foreach(hsh, rb_strhash_to_hash_i, &hsh);
|
466
|
+
return hsh;
|
492
467
|
}
|
493
468
|
|
494
469
|
void
|
@@ -496,7 +471,7 @@ Init_hwia()
|
|
496
471
|
{
|
497
472
|
id_hash = rb_intern("hash");
|
498
473
|
id_strhash = rb_intern("strhash");
|
499
|
-
|
474
|
+
hash_format = INT2FIX(536870923);
|
500
475
|
|
501
476
|
rb_cStrHash = rb_define_class("StrHash", rb_cHash);
|
502
477
|
|
@@ -512,7 +487,6 @@ Init_hwia()
|
|
512
487
|
/* revist, same API, but may be clobbered */
|
513
488
|
rb_define_method(rb_cStrHash, "dup", rb_hash_strhash, 0);
|
514
489
|
rb_define_method(rb_cStrHash, "strhash", rb_strhash_strhash, 0);
|
515
|
-
rb_define_method(rb_cStrHash, "convert", rb_strhash_convert, 1);
|
516
490
|
rb_define_method(rb_cStrHash, "[]=", rb_strhash_aset, 2);
|
517
491
|
rb_define_method(rb_cStrHash, "store", rb_strhash_aset, 2);
|
518
492
|
rb_define_method(rb_cStrHash, "update", rb_strhash_update, 1);
|
@@ -520,4 +494,4 @@ Init_hwia()
|
|
520
494
|
rb_define_method(rb_cStrHash, "merge", rb_strhash_merge, 1);
|
521
495
|
rb_define_method(rb_cStrHash, "to_hash", rb_strhash_to_hash, 0);
|
522
496
|
rb_define_method(rb_cHash, "strhash", rb_hash_strhash, 0);
|
523
|
-
}
|
497
|
+
}
|
data/hwia.gemspec
CHANGED