2 ** object.c - Object, NilClass, TrueClass, FalseClass class
4 ** See Copyright Notice in mruby.h
8 #include <mruby/class.h>
9 #include <mruby/numeric.h>
10 #include <mruby/string.h>
11 #include <mruby/class.h>
12 #include <mruby/internal.h>
13 #include <mruby/presym.h>
16 mrb_obj_eq(mrb_state
*mrb
, mrb_value v1
, mrb_value v2
)
18 #if defined(MRB_NAN_BOXING)
20 #elif defined(MRB_WORD_BOXING)
22 #else /* MRB_NO_BOXING */
23 if (mrb_type(v1
) != mrb_type(v2
)) return FALSE
;
24 switch (mrb_type(v1
)) {
29 return (mrb_fixnum(v1
) == mrb_fixnum(v2
));
31 return (mrb_integer(v1
) == mrb_integer(v2
));
33 return (mrb_symbol(v1
) == mrb_symbol(v2
));
37 return (mrb_float(v1
) == mrb_float(v2
));
41 return (mrb_ptr(v1
) == mrb_ptr(v2
));
47 mrb_obj_equal(mrb_state
*mrb
, mrb_value v1
, mrb_value v2
)
49 /* temporary definition */
50 return mrb_obj_eq(mrb
, v1
, v2
);
54 mrb_equal(mrb_state
*mrb
, mrb_value obj1
, mrb_value obj2
)
56 if (mrb_obj_eq(mrb
, obj1
, obj2
)) return TRUE
;
58 /* value mixing with integer and float */
59 else if (mrb_integer_p(obj1
) && mrb_float_p(obj2
)) {
60 if ((mrb_float
)mrb_integer(obj1
) == mrb_float(obj2
))
63 else if (mrb_float_p(obj1
) && mrb_integer_p(obj2
)) {
64 if (mrb_float(obj1
) == (mrb_float
)mrb_integer(obj2
))
69 else if (mrb_bigint_p(obj1
) &&
70 (mrb_integer_p(obj2
) || mrb_bigint_p(obj2
) || mrb_float_p(obj2
))) {
71 if (mrb_bint_cmp(mrb
, obj1
, obj2
) == 0)
75 else if (!mrb_func_basic_p(mrb
, obj1
, MRB_OPSYM(eq
), mrb_obj_equal_m
)) {
76 mrb_value result
= mrb_funcall_argv(mrb
, obj1
, MRB_OPSYM(eq
), 1, &obj2
);
77 if (mrb_test(result
)) return TRUE
;
83 * Document-class: NilClass
85 * The class of the singleton object <code>nil</code>.
93 * Only the object <i>nil</i> responds <code>true</code> to <code>nil?</code>.
97 mrb_true(mrb_state
*mrb
, mrb_value obj
)
99 return mrb_true_value();
107 * Always returns the empty string.
111 nil_to_s(mrb_state
*mrb
, mrb_value obj
)
113 mrb_value str
= mrb_str_new_frozen(mrb
, NULL
, 0);
114 RSTR_SET_ASCII_FLAG(mrb_str_ptr(str
));
119 nil_inspect(mrb_state
*mrb
, mrb_value obj
)
121 mrb_value str
= mrb_str_new_lit_frozen(mrb
, "nil");
122 RSTR_SET_ASCII_FLAG(mrb_str_ptr(str
));
126 /***********************************************************************
127 * Document-class: TrueClass
129 * The global value <code>true</code> is the only instance of class
130 * <code>TrueClass</code> and represents a logically true value in
131 * boolean expressions. The class provides operators allowing
132 * <code>true</code> to be used in logical expressions.
138 * true & obj -> true or false
140 * And---Returns <code>false</code> if <i>obj</i> is
141 * <code>nil</code> or <code>false</code>, <code>true</code> otherwise.
145 true_and(mrb_state
*mrb
, mrb_value obj
)
149 mrb_get_args(mrb
, "b", &obj2
);
151 return mrb_bool_value(obj2
);
159 * Exclusive Or---Returns <code>true</code> if <i>obj</i> is
160 * <code>nil</code> or <code>false</code>, <code>false</code>
165 true_xor(mrb_state
*mrb
, mrb_value obj
)
169 mrb_get_args(mrb
, "b", &obj2
);
170 return mrb_bool_value(!obj2
);
176 * true.to_s -> "true"
178 * The string representation of <code>true</code> is "true".
182 true_to_s(mrb_state
*mrb
, mrb_value obj
)
184 mrb_value str
= mrb_str_new_lit_frozen(mrb
, "true");
185 RSTR_SET_ASCII_FLAG(mrb_str_ptr(str
));
194 * Or---Returns <code>true</code>. As <i>anObject</i> is an argument to
195 * a method call, it is always evaluated; there is no short-circuit
196 * evaluation in this case.
199 * true || puts("logical or")
207 true_or(mrb_state
*mrb
, mrb_value obj
)
209 return mrb_true_value();
213 * Document-class: FalseClass
215 * The global value <code>false</code> is the only instance of class
216 * <code>FalseClass</code> and represents a logically false value in
217 * boolean expressions. The class provides operators allowing
218 * <code>false</code> to participate correctly in logical expressions.
226 * false & obj -> false
229 * And---Returns <code>false</code>. <i>obj</i> is always
230 * evaluated as it is the argument to a method call---there is no
231 * short-circuit evaluation in this case.
235 false_and(mrb_state
*mrb
, mrb_value obj
)
237 return mrb_false_value();
244 * false ^ obj -> true or false
245 * nil ^ obj -> true or false
247 * Exclusive Or---If <i>obj</i> is <code>nil</code> or
248 * <code>false</code>, returns <code>false</code>; otherwise, returns
254 false_xor(mrb_state
*mrb
, mrb_value obj
)
258 mrb_get_args(mrb
, "b", &obj2
);
259 return mrb_bool_value(obj2
);
266 * false | obj -> true or false
267 * nil | obj -> true or false
269 * Or---Returns <code>false</code> if <i>obj</i> is
270 * <code>nil</code> or <code>false</code>; <code>true</code> otherwise.
274 false_or(mrb_state
*mrb
, mrb_value obj
)
278 mrb_get_args(mrb
, "b", &obj2
);
279 return mrb_bool_value(obj2
);
285 * false.to_s -> "false"
291 false_to_s(mrb_state
*mrb
, mrb_value obj
)
293 mrb_value str
= mrb_str_new_lit_frozen(mrb
, "false");
294 RSTR_SET_ASCII_FLAG(mrb_str_ptr(str
));
299 mrb_init_object(mrb_state
*mrb
)
305 mrb
->nil_class
= n
= mrb_define_class_id(mrb
, MRB_SYM(NilClass
), mrb
->object_class
);
306 MRB_SET_INSTANCE_TT(n
, MRB_TT_FALSE
);
307 mrb_undef_class_method_id(mrb
, n
, MRB_SYM(new));
308 mrb_define_method_id(mrb
, n
, MRB_OPSYM(and), false_and
, MRB_ARGS_REQ(1)); /* 15.2.4.3.1 */
309 mrb_define_method_id(mrb
, n
, MRB_OPSYM(or), false_or
, MRB_ARGS_REQ(1)); /* 15.2.4.3.2 */
310 mrb_define_method_id(mrb
, n
, MRB_OPSYM(xor), false_xor
, MRB_ARGS_REQ(1)); /* 15.2.4.3.3 */
311 mrb_define_method_id(mrb
, n
, MRB_SYM_Q(nil
), mrb_true
, MRB_ARGS_NONE()); /* 15.2.4.3.4 */
312 mrb_define_method_id(mrb
, n
, MRB_SYM(to_s
), nil_to_s
, MRB_ARGS_NONE()); /* 15.2.4.3.5 */
313 mrb_define_method_id(mrb
, n
, MRB_SYM(inspect
), nil_inspect
, MRB_ARGS_NONE());
315 mrb
->true_class
= t
= mrb_define_class_id(mrb
, MRB_SYM(TrueClass
), mrb
->object_class
);
316 MRB_SET_INSTANCE_TT(t
, MRB_TT_TRUE
);
317 mrb_undef_class_method_id(mrb
, t
, MRB_SYM(new));
318 mrb_define_method_id(mrb
, t
, MRB_OPSYM(and), true_and
, MRB_ARGS_REQ(1)); /* 15.2.5.3.1 */
319 mrb_define_method_id(mrb
, t
, MRB_OPSYM(or), true_or
, MRB_ARGS_REQ(1)); /* 15.2.5.3.2 */
320 mrb_define_method_id(mrb
, t
, MRB_OPSYM(xor), true_xor
, MRB_ARGS_REQ(1)); /* 15.2.5.3.3 */
321 mrb_define_method_id(mrb
, t
, MRB_SYM(to_s
), true_to_s
, MRB_ARGS_NONE()); /* 15.2.5.3.4 */
322 mrb_define_method_id(mrb
, t
, MRB_SYM(inspect
), true_to_s
, MRB_ARGS_NONE());
324 mrb
->false_class
= f
= mrb_define_class_id(mrb
, MRB_SYM(FalseClass
), mrb
->object_class
);
325 MRB_SET_INSTANCE_TT(f
, MRB_TT_FALSE
);
326 mrb_undef_class_method_id(mrb
, f
, MRB_SYM(new));
327 mrb_define_method_id(mrb
, f
, MRB_OPSYM(and), false_and
, MRB_ARGS_REQ(1)); /* 15.2.6.3.1 */
328 mrb_define_method_id(mrb
, f
, MRB_OPSYM(or), false_or
, MRB_ARGS_REQ(1)); /* 15.2.6.3.2 */
329 mrb_define_method_id(mrb
, f
, MRB_OPSYM(xor), false_xor
, MRB_ARGS_REQ(1)); /* 15.2.6.3.3 */
330 mrb_define_method_id(mrb
, f
, MRB_SYM(to_s
), false_to_s
, MRB_ARGS_NONE()); /* 15.2.6.3.4 */
331 mrb_define_method_id(mrb
, f
, MRB_SYM(inspect
), false_to_s
, MRB_ARGS_NONE());
335 type_name(enum mrb_vtype t
)
338 #define MRB_VTYPE_NAME(tt, type, name) case tt: return name;
339 MRB_VTYPE_FOREACH(MRB_VTYPE_NAME
)
340 #undef MRB_VTYPE_NAME
341 default: return NULL
;
346 convert_type(mrb_state
*mrb
, mrb_value val
, const char *tname
, mrb_sym method
, mrb_bool raise
)
348 if (!mrb_respond_to(mrb
, val
, method
)) {
350 if (tname
) mrb_raisef(mrb
, E_TYPE_ERROR
, "can't convert %Y into %s", val
, tname
);
351 mrb_raisef(mrb
, E_TYPE_ERROR
, "can't convert %Y", val
);
353 return mrb_nil_value();
355 return mrb_funcall_argv(mrb
, val
, method
, 0, 0);
359 mrb_type_convert(mrb_state
*mrb
, mrb_value val
, enum mrb_vtype type
, mrb_sym method
)
364 if (mrb_type(val
) == type
) return val
;
365 tname
= type_name(type
);
366 v
= convert_type(mrb
, val
, tname
, method
, TRUE
);
367 if (mrb_type(v
) != type
) {
368 if (type
== MRB_TT_STRING
) return mrb_any_to_s(mrb
, val
);
369 mrb_raisef(mrb
, E_TYPE_ERROR
, "%v cannot be converted to %s by #%n", val
, tname
, method
);
375 mrb_type_convert_check(mrb_state
*mrb
, mrb_value val
, enum mrb_vtype type
, mrb_sym method
)
379 if (mrb_type(val
) == type
&& type
!= MRB_TT_CDATA
&& type
!= MRB_TT_ISTRUCT
) return val
;
380 v
= convert_type(mrb
, val
, type_name(type
), method
, FALSE
);
381 if (mrb_nil_p(v
) || mrb_type(v
) != type
) return mrb_nil_value();
386 mrb_check_type(mrb_state
*mrb
, mrb_value x
, enum mrb_vtype t
)
388 enum mrb_vtype xt
= mrb_type(x
);
389 const char *tname
, *ename
;
393 tname
= type_name(t
);
397 else if (mrb_integer_p(x
)) {
400 else if (mrb_symbol_p(x
)) {
403 else if (mrb_immediate_p(x
)) {
404 ename
= RSTRING_PTR(mrb_obj_as_string(mrb
, x
));
407 ename
= mrb_obj_classname(mrb
, x
);
410 mrb_raisef(mrb
, E_TYPE_ERROR
, "wrong argument type %s (expected %s)",
413 mrb_raisef(mrb
, E_TYPE_ERROR
, "unknown type %d (%s given)", t
, ename
);
421 * Returns a string representing <i>obj</i>. The default
422 * <code>to_s</code> prints the object's class and an encoding of the
423 * object id. As a special case, the top-level object that is the
424 * initial execution context of Ruby programs returns "main."
428 mrb_any_to_s(mrb_state
*mrb
, mrb_value obj
)
430 mrb_value str
= mrb_str_new_capa(mrb
, 20);
431 const char *cname
= mrb_obj_classname(mrb
, obj
);
433 mrb_str_cat_lit(mrb
, str
, "#<");
434 mrb_str_cat_cstr(mrb
, str
, cname
);
435 if (!mrb_immediate_p(obj
)) {
436 mrb_str_cat_lit(mrb
, str
, ":");
437 mrb_str_cat_str(mrb
, str
, mrb_ptr_to_str(mrb
, mrb_ptr(obj
)));
439 mrb_str_cat_lit(mrb
, str
, ">");
446 * obj.is_a?(class) => true or false
447 * obj.kind_of?(class) => true or false
449 * Returns <code>true</code> if <i>class</i> is the class of
450 * <i>obj</i>, or if <i>class</i> is one of the superclasses of
451 * <i>obj</i> or modules included in <i>obj</i>.
460 * b.instance_of? A #=> false
461 * b.instance_of? B #=> true
462 * b.instance_of? C #=> false
463 * b.instance_of? M #=> false
464 * b.kind_of? A #=> true
465 * b.kind_of? B #=> true
466 * b.kind_of? C #=> false
467 * b.kind_of? M #=> true
471 mrb_obj_is_kind_of(mrb_state
*mrb
, mrb_value obj
, struct RClass
*c
)
473 struct RClass
*cl
= mrb_class(mrb
, obj
);
483 mrb_raise(mrb
, E_TYPE_ERROR
, "class or module required");
488 if (cl
== c
|| cl
->mt
== c
->mt
)
495 #ifdef MRB_USE_RATIONAL
496 // provided by mruby-rational with MRB_USE_RATIONAL
497 mrb_value
mrb_rational_to_i(mrb_state
*mrb
, mrb_value rat
);
498 mrb_value
mrb_rational_to_f(mrb_state
*mrb
, mrb_value rat
);
500 #ifdef MRB_USE_COMPLEX
501 // provided by mruby-complex with MRB_USE_COMPLEX
502 mrb_value
mrb_complex_to_f(mrb_state
*mrb
, mrb_value comp
);
503 mrb_value
mrb_complex_to_i(mrb_state
*mrb
, mrb_value comp
);
507 mrb_ensure_integer_type(mrb_state
*mrb
, mrb_value val
)
509 if (!mrb_integer_p(val
)) {
511 if (mrb_float_p(val
)) {
512 return mrb_float_to_integer(mrb
, val
);
515 switch (mrb_type(val
)) {
516 #ifdef MRB_USE_BIGINT
520 #ifdef MRB_USE_RATIONAL
521 case MRB_TT_RATIONAL
:
522 return mrb_rational_to_i(mrb
, val
);
524 #ifdef MRB_USE_COMPLEX
526 return mrb_complex_to_i(mrb
, val
);
533 mrb_raisef(mrb
, E_TYPE_ERROR
, "%Y cannot be converted to Integer", val
);
539 mrb_ensure_int_type(mrb_state
*mrb
, mrb_value val
)
541 val
= mrb_ensure_integer_type(mrb
, val
);
542 #ifdef MRB_USE_BIGINT
543 if (mrb_bigint_p(val
)) {
544 return mrb_int_value(mrb
, mrb_bint_as_int(mrb
, val
));
552 mrb_ensure_float_type(mrb_state
*mrb
, mrb_value val
)
554 if (mrb_nil_p(val
)) {
555 mrb_raise(mrb
, E_TYPE_ERROR
, "can't convert nil into Float");
557 switch (mrb_type(val
)) {
559 return mrb_float_value(mrb
, (mrb_float
)mrb_integer(val
));
564 #ifdef MRB_USE_RATIONAL
565 case MRB_TT_RATIONAL
:
566 return mrb_rational_to_f(mrb
, val
);
569 #ifdef MRB_USE_COMPLEX
571 return mrb_complex_to_f(mrb
, val
);
574 #ifdef MRB_USE_BIGINT
576 return mrb_float_value(mrb
, mrb_bint_as_float(mrb
, val
));
580 mrb_raisef(mrb
, E_TYPE_ERROR
, "%Y cannot be converted to Float", val
);
588 mrb_ensure_string_type(mrb_state
*mrb
, mrb_value str
)
590 if (!mrb_string_p(str
)) {
591 mrb_raisef(mrb
, E_TYPE_ERROR
, "%Y cannot be converted to String", str
);
597 mrb_check_string_type(mrb_state
*mrb
, mrb_value str
)
599 if (!mrb_string_p(str
)) return mrb_nil_value();
604 mrb_ensure_array_type(mrb_state
*mrb
, mrb_value ary
)
606 if (!mrb_array_p(ary
)) {
607 mrb_raisef(mrb
, E_TYPE_ERROR
, "%Y cannot be converted to Array", ary
);
613 mrb_check_array_type(mrb_state
*mrb
, mrb_value ary
)
615 if (!mrb_array_p(ary
)) return mrb_nil_value();
620 mrb_ensure_hash_type(mrb_state
*mrb
, mrb_value hash
)
622 if (!mrb_hash_p(hash
)) {
623 mrb_raisef(mrb
, E_TYPE_ERROR
, "%Y cannot be converted to Hash", hash
);
629 mrb_check_hash_type(mrb_state
*mrb
, mrb_value hash
)
631 if (!mrb_hash_p(hash
)) return mrb_nil_value();
636 mrb_inspect(mrb_state
*mrb
, mrb_value obj
)
638 mrb_value v
= mrb_funcall_argv(mrb
, obj
, MRB_SYM(inspect
), 0, NULL
);
639 if (!mrb_string_p(v
)) {
640 v
= mrb_obj_as_string(mrb
, obj
);
646 mrb_eql(mrb_state
*mrb
, mrb_value obj1
, mrb_value obj2
)
648 if (mrb_obj_eq(mrb
, obj1
, obj2
)) return TRUE
;
649 return mrb_test(mrb_funcall_argv(mrb
, obj1
, MRB_SYM_Q(eql
), 1, &obj2
));
653 mrb_obj_itself(mrb_state
*mrb
, mrb_value self
)