|
11 | 11 | #include <mruby/hash.h> |
12 | 12 | #include <mruby/string.h> |
13 | 13 | #include <mruby/variable.h> |
| 14 | +#include <mruby/proc.h> |
14 | 15 | #include <mruby/internal.h> |
15 | 16 | #include <mruby/presym.h> |
16 | 17 |
|
@@ -1273,6 +1274,21 @@ mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val) |
1273 | 1274 | mrb_field_write_barrier_value(mrb, mrb_basic_ptr(hash), key); |
1274 | 1275 | mrb_field_write_barrier_value(mrb, mrb_basic_ptr(hash), val); |
1275 | 1276 | } |
| 1277 | +static void |
| 1278 | +hash_set_default_proc(mrb_state *mrb, mrb_value hash, mrb_value proc) |
| 1279 | +{ |
| 1280 | + struct RProc *p = mrb_proc_ptr(proc); |
| 1281 | + if (MRB_PROC_STRICT_P(p)) { |
| 1282 | + int n = mrb_proc_arity(p); |
| 1283 | + if (n != 2 && (n >= 0 || n < -3)) { |
| 1284 | + if (n < 0) n = -n-1; |
| 1285 | + mrb_raisef(mrb, E_TYPE_ERROR, "default_proc takes two arguments (2 for %d)", n); |
| 1286 | + } |
| 1287 | + } |
| 1288 | + mrb_iv_set(mrb, hash, MRB_SYM(ifnone), proc); |
| 1289 | + RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT; |
| 1290 | + RHASH(hash)->flags |= MRB_HASH_DEFAULT; |
| 1291 | +} |
1276 | 1292 |
|
1277 | 1293 | /* 15.2.13.4.16 */ |
1278 | 1294 | /* |
@@ -1323,10 +1339,10 @@ mrb_hash_init(mrb_state *mrb, mrb_value hash) |
1323 | 1339 | if (ifnone_p) { |
1324 | 1340 | mrb_argnum_error(mrb, 1, 0, 0); |
1325 | 1341 | } |
1326 | | - RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT; |
1327 | | - ifnone = block; |
| 1342 | + hash_set_default_proc(mrb, hash, block); |
| 1343 | + return hash; |
1328 | 1344 | } |
1329 | | - if (!mrb_nil_p(ifnone)) { |
| 1345 | + if (ifnone_p && !mrb_nil_p(ifnone)) { |
1330 | 1346 | RHASH(hash)->flags |= MRB_HASH_DEFAULT; |
1331 | 1347 | mrb_iv_set(mrb, hash, MRB_SYM(ifnone), ifnone); |
1332 | 1348 | } |
@@ -1482,14 +1498,12 @@ mrb_hash_set_default_proc(mrb_state *mrb, mrb_value hash) |
1482 | 1498 | } |
1483 | 1499 | mrb_iv_set(mrb, hash, MRB_SYM(ifnone), ifnone); |
1484 | 1500 | if (!mrb_nil_p(ifnone)) { |
1485 | | - RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT; |
1486 | | - RHASH(hash)->flags |= MRB_HASH_DEFAULT; |
| 1501 | + hash_set_default_proc(mrb, hash, ifnone); |
1487 | 1502 | } |
1488 | 1503 | else { |
1489 | 1504 | RHASH(hash)->flags &= ~MRB_HASH_DEFAULT; |
1490 | 1505 | RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT; |
1491 | 1506 | } |
1492 | | - |
1493 | 1507 | return ifnone; |
1494 | 1508 | } |
1495 | 1509 |
|
|
0 commit comments