summaryrefslogtreecommitdiff
path: root/object.c
diff options
context:
space:
mode:
Diffstat (limited to 'object.c')
-rw-r--r--object.c482
1 files changed, 293 insertions, 189 deletions
diff --git a/object.c b/object.c
index 28e6125421..2e962b1c3c 100644
--- a/object.c
+++ b/object.c
@@ -46,10 +46,9 @@
/* Flags of RObject
*
- * 1: ROBJECT_EMBED
- * The object has its instance variables embedded (the array of
- * instance variables directly follow the object, rather than being
- * on a separately allocated buffer).
+ * 4: ROBJECT_HEAP
+ * The object has its instance variables in a separately allocated buffer.
+ * This can be either a flat buffer of reference, or an st_table for complex objects.
*/
/*!
@@ -91,11 +90,6 @@ static ID id_instance_variables_to_inspect;
/*! \endcond */
-size_t
-rb_obj_embedded_size(uint32_t fields_count)
-{
- return offsetof(struct RObject, as.ary) + (sizeof(VALUE) * fields_count);
-}
VALUE
rb_obj_hide(VALUE obj)
@@ -115,34 +109,6 @@ rb_obj_reveal(VALUE obj, VALUE klass)
return obj;
}
-VALUE
-rb_class_allocate_instance(VALUE klass)
-{
- uint32_t index_tbl_num_entries = RCLASS_MAX_IV_COUNT(klass);
-
- size_t size = rb_obj_embedded_size(index_tbl_num_entries);
- if (!rb_gc_size_allocatable_p(size)) {
- size = sizeof(struct RObject);
- }
-
- NEWOBJ_OF(o, struct RObject, klass,
- T_OBJECT | ROBJECT_EMBED | (RGENGC_WB_PROTECTED_OBJECT ? FL_WB_PROTECTED : 0), size, 0);
- VALUE obj = (VALUE)o;
-
- RUBY_ASSERT(RSHAPE_TYPE_P(RBASIC_SHAPE_ID(obj), SHAPE_ROOT));
-
- RBASIC_SET_SHAPE_ID(obj, rb_shape_root(rb_gc_heap_id_for_size(size)));
-
-#if RUBY_DEBUG
- RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
- VALUE *ptr = ROBJECT_FIELDS(obj);
- for (size_t i = 0; i < ROBJECT_FIELDS_CAPACITY(obj); i++) {
- ptr[i] = Qundef;
- }
-#endif
-
- return obj;
-}
VALUE
rb_obj_setup(VALUE obj, VALUE klass, VALUE type)
@@ -161,7 +127,7 @@ rb_obj_setup(VALUE obj, VALUE klass, VALUE type)
*
* Returns +true+ or +false+.
*
- * Like Object#==, if +object+ is an instance of Object
+ * Like Object#==, if +other+ is an instance of \Object
* (and not an instance of one of its many subclasses).
*
* This method is commonly overridden by those subclasses,
@@ -199,14 +165,18 @@ rb_eql(VALUE obj1, VALUE obj2)
/**
* call-seq:
- * obj == other -> true or false
- * obj.equal?(other) -> true or false
- * obj.eql?(other) -> true or false
+ * self == other -> true or false
+ * equal?(other) -> true or false
+ * eql?(other) -> true or false
+ *
+ * Returns whether +self+ and +other+ are the same object:
*
- * Equality --- At the Object level, #== returns <code>true</code>
- * only if +obj+ and +other+ are the same object. Typically, this
- * method is overridden in descendant classes to provide
- * class-specific meaning.
+ * object = Object.new
+ * object == object # => true
+ * object == Object.new # => false
+ *
+ * Here in class \Object, #==, #equal?, and #eql? are the same method.
+ * A subclass may override #== to provide class-specific meaning.
*
* Unlike #==, the #equal? method should never be overridden by
* subclasses as it is used to determine object identity (that is,
@@ -279,12 +249,38 @@ rb_obj_not_equal(VALUE obj1, VALUE obj2)
return rb_obj_not(result);
}
+static inline VALUE
+fake_class_p(VALUE klass)
+{
+ RUBY_ASSERT(klass);
+ RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_MODULE) || RB_TYPE_P(klass, T_ICLASS));
+ STATIC_ASSERT(t_iclass_overlap_t_class, !(T_CLASS & T_ICLASS));
+ STATIC_ASSERT(t_iclass_overlap_t_module, !(T_MODULE & T_ICLASS));
+
+ return FL_TEST_RAW(klass, T_ICLASS | FL_SINGLETON);
+}
+
+static inline VALUE
+class_real(VALUE cl)
+{
+ RUBY_ASSERT(cl);
+
+ // TODO: In the future we should only call this with T_CLASS
+ RUBY_ASSERT(RB_TYPE_P(cl, T_CLASS) || RB_TYPE_P(cl, T_ICLASS) || RB_TYPE_P(cl, T_MODULE));
+
+ while (RB_UNLIKELY(fake_class_p(cl))) {
+ // All paths through super in any box will eventually result in the
+ // same class.
+ cl = RCLASSEXT_SUPER(RCLASS_EXT_PRIME(cl));
+ }
+ return cl;
+}
+
VALUE
rb_class_real(VALUE cl)
{
- while (cl &&
- (RCLASS_SINGLETON_P(cl) || BUILTIN_TYPE(cl) == T_ICLASS)) {
- cl = RCLASS_SUPER(cl);
+ if (cl) {
+ cl = class_real(cl);
}
return cl;
}
@@ -292,7 +288,17 @@ rb_class_real(VALUE cl)
VALUE
rb_obj_class(VALUE obj)
{
- return rb_class_real(CLASS_OF(obj));
+ VALUE cl = CLASS_OF(obj);
+ if (cl) {
+ cl = class_real(cl);
+ }
+ return cl;
+}
+
+static inline VALUE
+rb_obj_class_must(VALUE obj)
+{
+ return class_real(CLASS_OF(obj));
}
/*
@@ -322,8 +328,8 @@ rb_obj_singleton_class(VALUE obj)
void
rb_obj_copy_ivar(VALUE dest, VALUE obj)
{
- RUBY_ASSERT(!RB_TYPE_P(obj, T_CLASS) && !RB_TYPE_P(obj, T_MODULE));
- RUBY_ASSERT(BUILTIN_TYPE(dest) == BUILTIN_TYPE(obj));
+ RUBY_ASSERT(RB_TYPE_P(obj, T_OBJECT));
+ RUBY_ASSERT(RB_TYPE_P(dest, T_OBJECT));
unsigned long src_num_ivs = rb_ivar_count(obj);
if (!src_num_ivs) {
@@ -332,7 +338,7 @@ rb_obj_copy_ivar(VALUE dest, VALUE obj)
shape_id_t src_shape_id = RBASIC_SHAPE_ID(obj);
- if (rb_shape_too_complex_p(src_shape_id)) {
+ if (rb_shape_complex_p(src_shape_id)) {
rb_shape_copy_complex_ivars(dest, obj, src_shape_id, ROBJECT_FIELDS_HASH(obj));
return;
}
@@ -341,10 +347,10 @@ rb_obj_copy_ivar(VALUE dest, VALUE obj)
RUBY_ASSERT(RSHAPE_TYPE_P(initial_shape_id, SHAPE_ROOT));
shape_id_t dest_shape_id = rb_shape_rebuild(initial_shape_id, src_shape_id);
- if (UNLIKELY(rb_shape_too_complex_p(dest_shape_id))) {
+ if (UNLIKELY(rb_shape_complex_p(dest_shape_id))) {
st_table *table = rb_st_init_numtable_with_size(src_num_ivs);
rb_obj_copy_ivs_to_hash_table(obj, table);
- rb_obj_init_too_complex(dest, table);
+ rb_obj_init_complex(dest, table);
return;
}
@@ -362,7 +368,7 @@ rb_obj_copy_ivar(VALUE dest, VALUE obj)
}
rb_shape_copy_fields(dest, dest_buf, dest_shape_id, src_buf, src_shape_id);
- rb_obj_set_shape_id(dest, dest_shape_id);
+ RBASIC_SET_SHAPE_ID(dest, dest_shape_id);
}
static void
@@ -380,7 +386,7 @@ init_copy(VALUE dest, VALUE obj)
break;
case T_CLASS:
case T_MODULE:
- // noop: handled in class.c: rb_mod_init_copy
+ rb_mod_init_copy(dest, obj);
break;
case T_OBJECT:
rb_obj_copy_ivar(dest, obj);
@@ -495,8 +501,8 @@ rb_obj_clone_setup(VALUE obj, VALUE clone, VALUE kwfreeze)
}
if (RB_OBJ_FROZEN(obj)) {
- shape_id_t next_shape_id = rb_shape_transition_frozen(clone);
- rb_obj_set_shape_id(clone, next_shape_id);
+ shape_id_t next_shape_id = rb_obj_shape_transition_frozen(clone);
+ RBASIC_SET_SHAPE_ID(clone, next_shape_id);
}
break;
case Qtrue: {
@@ -763,7 +769,7 @@ inspect_obj(VALUE obj, VALUE a, int recur)
rb_str_cat2(str, " ...");
}
else {
- rb_ivar_foreach(obj, inspect_i, a);
+ rb_ivar_foreach_buffered(obj, inspect_i, a);
}
rb_str_cat2(str, ">");
RSTRING_PTR(str)[0] = '#';
@@ -822,14 +828,21 @@ rb_obj_inspect(VALUE obj)
{
VALUE ivars = rb_check_funcall(obj, id_instance_variables_to_inspect, 0, 0);
st_index_t n = 0;
- if (UNDEF_P(ivars)) {
+ if (UNDEF_P(ivars) || NIL_P(ivars)) {
n = rb_ivar_count(obj);
ivars = Qnil;
}
- else if (!NIL_P(ivars)) {
- Check_Type(ivars, T_ARRAY);
+ else if (RB_TYPE_P(ivars, T_ARRAY)) {
n = RARRAY_LEN(ivars);
}
+ else {
+ rb_raise(
+ rb_eTypeError,
+ "Expected #instance_variables_to_inspect to return an Array or nil, but it returned %"PRIsVALUE,
+ rb_obj_class(ivars)
+ );
+ }
+
if (n > 0) {
VALUE c = rb_class_name(CLASS_OF(obj));
VALUE args[2] = {
@@ -843,6 +856,13 @@ rb_obj_inspect(VALUE obj)
}
}
+/* :nodoc: */
+static VALUE
+rb_obj_instance_variables_to_inspect(VALUE obj)
+{
+ return Qnil;
+}
+
static VALUE
class_or_module_required(VALUE c)
{
@@ -1535,10 +1555,10 @@ rb_true_to_s(VALUE obj)
/*
- * call-seq:
- * true & object -> true or false
+ * call-seq:
+ * true & object -> true or false
*
- * Returns +false+ if +object+ is +false+ or +nil+, +true+ otherwise:
+ * Returns +false+ if +object+ is +false+ or +nil+, +true+ otherwise:
*
* true & Object.new # => true
* true & false # => false
@@ -1721,21 +1741,33 @@ rb_obj_not_match(VALUE obj1, VALUE obj2)
/*
* call-seq:
- * obj <=> other -> 0 or nil
+ * self <=> other -> 0 or nil
+ *
+ * Compares +self+ and +other+.
+ *
+ * Returns:
+ *
+ * - +0+, if +self+ and +other+ are the same object,
+ * or if <tt>self == other</tt>.
+ * - +nil+, otherwise.
+ *
+ * Examples:
+ *
+ * o = Object.new
+ * o <=> o # => 0
+ * o <=> o.dup # => nil
*
- * Returns 0 if +obj+ and +other+ are the same object
- * or <code>obj == other</code>, otherwise nil.
+ * A class that includes module Comparable
+ * should override this method by defining an instance method that:
*
- * The #<=> is used by various methods to compare objects, for example
- * Enumerable#sort, Enumerable#max etc.
+ * - Take one argument, +other+.
+ * - Returns:
*
- * Your implementation of #<=> should return one of the following values: -1, 0,
- * 1 or nil. -1 means self is smaller than other. 0 means self is equal to other.
- * 1 means self is bigger than other. Nil means the two values could not be
- * compared.
+ * - +-1+, if +self+ is less than +other+.
+ * - +0+, if +self+ is equal to +other+.
+ * - +1+, if +self+ is greater than +other+.
+ * - +nil+, if the two values are incommensurate.
*
- * When you define #<=>, you can include Comparable to gain the
- * methods #<=, #<, #==, #>=, #> and #between?.
*/
static VALUE
rb_obj_cmp(VALUE obj1, VALUE obj2)
@@ -1835,11 +1867,12 @@ rb_mod_freeze(VALUE mod)
/*
* call-seq:
- * mod === obj -> true or false
+ * self === other -> true or false
*
- * Case Equality---Returns <code>true</code> if <i>obj</i> is an
- * instance of <i>mod</i> or an instance of one of <i>mod</i>'s descendants.
- * Of limited use for modules, but can be used in <code>case</code> statements
+ * Returns whether +other+ is an instance of +self+,
+ * or is an instance of a subclass of +self+.
+ *
+ * Of limited use for modules, but can be used in +case+ statements
* to classify objects by class.
*/
@@ -1851,13 +1884,27 @@ rb_mod_eqq(VALUE mod, VALUE arg)
/*
* call-seq:
- * mod <= other -> true, false, or nil
+ * self <= other -> true, false, or nil
+ *
+ * Compares +self+ and +other+ with respect to ancestry and inclusion.
+ *
+ * Returns +nil+ if there is no such relationship between the two:
+ *
+ * Array <= Hash # => nil
+ *
+ * Otherwise, returns +true+ if +other+ is an ancestor of +self+,
+ * or if +self+ includes +other+,
+ * or if the two are the same:
+ *
+ * File <= IO # => true # IO is an ancestor of File.
+ * Array <= Enumerable # => true # Array includes Enumerable.
+ * Array <= Array # => true
+ *
+ * Otherwise, returns +false+:
+ *
+ * IO <= File # => false
+ * Enumerable <= Array # => false
*
- * Returns true if <i>mod</i> is a subclass of <i>other</i> or
- * is the same as <i>other</i>. Returns
- * <code>nil</code> if there's no relationship between the two.
- * (Think of the relationship in terms of the class definition:
- * "class A < B" implies "A < B".)
*/
VALUE
@@ -1903,14 +1950,26 @@ rb_class_inherited_p(VALUE mod, VALUE arg)
/*
* call-seq:
- * mod < other -> true, false, or nil
+ * self < other -> true, false, or nil
+ *
+ * Returns +true+ if +self+ is a descendant of +other+
+ * (+self+ is a subclass of +other+ or +self+ includes +other+):
+ *
+ * Float < Numeric # => true
+ * Array < Enumerable # => true
+ *
+ * Returns +false+ if +self+ is an ancestor of +other+
+ * (+self+ is a superclass of +other+ or +self+ is included in +other+) or
+ * if +self+ is the same as +other+:
*
- * Returns true if <i>mod</i> is a subclass of <i>other</i>. Returns
- * <code>false</code> if <i>mod</i> is the same as <i>other</i>
- * or <i>mod</i> is an ancestor of <i>other</i>.
- * Returns <code>nil</code> if there's no relationship between the two.
- * (Think of the relationship in terms of the class definition:
- * "class A < B" implies "A < B".)
+ * Numeric < Float # => false
+ * Enumerable < Array # => false
+ * Float < Float # => false
+ *
+ * Returns +nil+ if there is no relationship between the two:
+ *
+ * Float < Hash # => nil
+ * Enumerable < String # => nil
*
*/
@@ -1924,13 +1983,28 @@ rb_mod_lt(VALUE mod, VALUE arg)
/*
* call-seq:
- * mod >= other -> true, false, or nil
+ * self >= other -> true, false, or nil
+ *
+ * Compares +self+ and +other+ with respect to ancestry and inclusion.
+ *
+ * Returns +true+ if +self+ is an ancestor of +other+
+ * (+self+ is a superclass of +other+ or +self+ is included in +other+) or
+ * if +self+ is the same as +other+:
*
- * Returns true if <i>mod</i> is an ancestor of <i>other</i>, or the
- * two modules are the same. Returns
- * <code>nil</code> if there's no relationship between the two.
- * (Think of the relationship in terms of the class definition:
- * "class A < B" implies "B > A".)
+ * Numeric >= Float # => true
+ * Enumerable >= Array # => true
+ * Float >= Float # => true
+ *
+ * Returns +false+ if +self+ is a descendant of +other+
+ * (+self+ is a subclass of +other+ or +self+ includes +other+):
+ *
+ * Float >= Numeric # => false
+ * Array >= Enumerable # => false
+ *
+ * Returns +nil+ if there is no relationship between the two:
+ *
+ * Float >= Hash # => nil
+ * Enumerable >= String # => nil
*
*/
@@ -1946,14 +2020,26 @@ rb_mod_ge(VALUE mod, VALUE arg)
/*
* call-seq:
- * mod > other -> true, false, or nil
+ * self > other -> true, false, or nil
+ *
+ * Returns +true+ if +self+ is an ancestor of +other+
+ * (+self+ is a superclass of +other+ or +self+ is included in +other+):
+ *
+ * Numeric > Float # => true
+ * Enumerable > Array # => true
+ *
+ * Returns +false+ if +self+ is a descendant of +other+
+ * (+self+ is a subclass of +other+ or +self+ includes +other+) or
+ * if +self+ is the same as +other+:
+ *
+ * Float > Numeric # => false
+ * Array > Enumerable # => false
+ * Float > Float # => false
*
- * Returns true if <i>mod</i> is an ancestor of <i>other</i>. Returns
- * <code>false</code> if <i>mod</i> is the same as <i>other</i>
- * or <i>mod</i> is a descendant of <i>other</i>.
- * Returns <code>nil</code> if there's no relationship between the two.
- * (Think of the relationship in terms of the class definition:
- * "class A < B" implies "B > A".)
+ * Returns +nil+ if there is no relationship between the two:
+ *
+ * Float > Hash # => nil
+ * Enumerable > String # => nil
*
*/
@@ -1966,14 +2052,30 @@ rb_mod_gt(VALUE mod, VALUE arg)
/*
* call-seq:
- * module <=> other_module -> -1, 0, +1, or nil
+ * self <=> other -> -1, 0, 1, or nil
+ *
+ * Compares +self+ and +other+.
+ *
+ * Returns:
+ *
+ * - +-1+, if +self+ includes +other+, if or +self+ is a subclass of +other+.
+ * - +0+, if +self+ and +other+ are the same.
+ * - +1+, if +other+ includes +self+, or if +other+ is a subclass of +self+.
+ * - +nil+, if none of the above is true.
*
- * Comparison---Returns -1, 0, +1 or nil depending on whether +module+
- * includes +other_module+, they are the same, or if +module+ is included by
- * +other_module+.
+ * Examples:
+ *
+ * # Class Array includes module Enumerable.
+ * Array <=> Enumerable # => -1
+ * Enumerable <=> Enumerable # => 0
+ * Enumerable <=> Array # => 1
+ * # Class File is a subclass of class IO.
+ * File <=> IO # => -1
+ * File <=> File # => 0
+ * IO <=> File # => 1
+ * # Class File has no relationship to class String.
+ * File <=> String # => nil
*
- * Returns +nil+ if +module+ has no relationship with +other_module+, if
- * +other_module+ is not a module, or if the two values are incomparable.
*/
static VALUE
@@ -1998,28 +2100,52 @@ static VALUE rb_mod_initialize_exec(VALUE module);
/*
* call-seq:
- * Module.new -> mod
- * Module.new {|mod| block } -> mod
+ * Module.new -> new_module
+ * Module.new {|module| ... } -> new_module
*
- * Creates a new anonymous module. If a block is given, it is passed
- * the module object, and the block is evaluated in the context of this
- * module like #module_eval.
+ * Returns a new anonymous module.
*
- * fred = Module.new do
- * def meth1
- * "hello"
- * end
- * def meth2
- * "bye"
- * end
- * end
- * a = "my string"
- * a.extend(fred) #=> "my string"
- * a.meth1 #=> "hello"
- * a.meth2 #=> "bye"
+ * The module may be assigned to a name,
+ * which should be a constant name
+ * in capitalized {camel case}[https://en.wikipedia.org/wiki/Camel_case]
+ * (e.g., +MyModule+, not +MY_MODULE+).
+ *
+ * With no block given, returns the new module.
+ *
+ * MyModule = Module.new
+ * MyModule.class # => Module
+ * MyModule.name # => "MyModule"
+ *
+ * With a block given, calls the block with the new (not yet named) module:
+ *
+ * MyModule = Module.new {|m| p [m.class, m.name] }
+ * # => MyModule
+ * MyModule.class # => Module
+ MyModule.name # => "MyModule"
+ *
+ * Output (from the block):
+ *
+ * [Module, nil]
+ *
+ * The block may define methods and constants for the module:
+ *
+ * MyModule = Module.new do |m|
+ * MY_CONSTANT = "#{MyModule} constant value"
+ * def self.method1 = "#{MyModule} first method (singleton)"
+ * def method2 = "#{MyModule} Second method (instance)"
+ * end
+ * MyModule.method1 # => "MyModule first method (singleton)"
+ * class Foo
+ * include MyModule
+ * def speak
+ * MY_CONSTANT
+ * end
+ * end
+ * foo = Foo.new
+ * foo.method2 # => "MyModule Second method (instance)"
+ * foo.speak
+ * # => "MyModule constant value"
*
- * Assign the module to a constant (name starting uppercase) if you
- * want to treat it like a regular module.
*/
static VALUE
@@ -2098,6 +2224,8 @@ rb_class_initialize(int argc, VALUE *argv, VALUE klass)
}
}
rb_class_set_super(klass, super);
+ RCLASS_SET_MAX_IV_COUNT(klass, RCLASS_MAX_IV_COUNT(super));
+ RCLASS_SET_ALLOCATOR(klass, RCLASS_ALLOCATOR(super));
rb_make_metaclass(klass, RBASIC(super)->klass);
rb_class_inherited(super, klass);
rb_mod_initialize_exec(klass);
@@ -2141,6 +2269,7 @@ static VALUE class_call_alloc_func(rb_alloc_func_t allocator, VALUE klass);
static VALUE
rb_class_alloc(VALUE klass)
{
+ RBIMPL_ASSERT_TYPE(klass, T_CLASS);
rb_alloc_func_t allocator = class_get_alloc_func(klass);
return class_call_alloc_func(allocator, klass);
}
@@ -2163,6 +2292,15 @@ class_get_alloc_func(VALUE klass)
return allocator;
}
+// Might return NULL.
+rb_alloc_func_t
+rb_zjit_class_get_alloc_func(VALUE klass)
+{
+ assert(RCLASS_INITIALIZED_P(klass));
+ assert(!RCLASS_SINGLETON_P(klass));
+ return rb_get_alloc_func(klass);
+}
+
static VALUE
class_call_alloc_func(rb_alloc_func_t allocator, VALUE klass)
{
@@ -2172,9 +2310,7 @@ class_call_alloc_func(rb_alloc_func_t allocator, VALUE klass)
obj = (*allocator)(klass);
- if (rb_obj_class(obj) != rb_class_real(klass)) {
- rb_raise(rb_eTypeError, "wrong instance allocation");
- }
+ RUBY_ASSERT(rb_obj_class(obj) == rb_class_real(klass));
return obj;
}
@@ -3166,19 +3302,12 @@ convert_type_with_id(VALUE val, const char *tname, ID method, int raise, int ind
VALUE r = rb_check_funcall(val, method, 0, 0);
if (UNDEF_P(r)) {
if (raise) {
- const char *msg =
- ((index < 0 ? conv_method_index(rb_id2name(method)) : index)
- < IMPLICIT_CONVERSIONS) ?
- "no implicit conversion of" : "can't convert";
- const char *cname = NIL_P(val) ? "nil" :
- val == Qtrue ? "true" :
- val == Qfalse ? "false" :
- NULL;
- if (cname)
- rb_raise(rb_eTypeError, "%s %s into %s", msg, cname, tname);
- rb_raise(rb_eTypeError, "%s %"PRIsVALUE" into %s", msg,
- rb_obj_class(val),
- tname);
+ if ((index < 0 ? conv_method_index(rb_id2name(method)) : index) < IMPLICIT_CONVERSIONS) {
+ rb_no_implicit_conversion(val, tname);
+ }
+ else {
+ rb_cant_convert(val, tname);
+ }
}
return Qnil;
}
@@ -3194,17 +3323,6 @@ convert_type(VALUE val, const char *tname, const char *method, int raise)
return convert_type_with_id(val, tname, m, raise, i);
}
-/*! \private */
-NORETURN(static void conversion_mismatch(VALUE, const char *, const char *, VALUE));
-static void
-conversion_mismatch(VALUE val, const char *tname, const char *method, VALUE result)
-{
- VALUE cname = rb_obj_class(val);
- rb_raise(rb_eTypeError,
- "can't convert %"PRIsVALUE" to %s (%"PRIsVALUE"#%s gives %"PRIsVALUE")",
- cname, tname, cname, method, rb_obj_class(result));
-}
-
VALUE
rb_convert_type(VALUE val, int type, const char *tname, const char *method)
{
@@ -3213,7 +3331,7 @@ rb_convert_type(VALUE val, int type, const char *tname, const char *method)
if (TYPE(val) == type) return val;
v = convert_type(val, tname, method, TRUE);
if (TYPE(v) != type) {
- conversion_mismatch(val, tname, method, v);
+ rb_cant_convert_invalid_return(val, tname, method, v);
}
return v;
}
@@ -3227,7 +3345,7 @@ rb_convert_type_with_id(VALUE val, int type, const char *tname, ID method)
if (TYPE(val) == type) return val;
v = convert_type_with_id(val, tname, method, TRUE, -1);
if (TYPE(v) != type) {
- conversion_mismatch(val, tname, RSTRING_PTR(rb_id2str(method)), v);
+ rb_cant_convert_invalid_return(val, tname, rb_id2name(method), v);
}
return v;
}
@@ -3242,7 +3360,7 @@ rb_check_convert_type(VALUE val, int type, const char *tname, const char *method
v = convert_type(val, tname, method, FALSE);
if (NIL_P(v)) return Qnil;
if (TYPE(v) != type) {
- conversion_mismatch(val, tname, method, v);
+ rb_cant_convert_invalid_return(val, tname, method, v);
}
return v;
}
@@ -3258,7 +3376,7 @@ rb_check_convert_type_with_id(VALUE val, int type, const char *tname, ID method)
v = convert_type_with_id(val, tname, method, FALSE, -1);
if (NIL_P(v)) return Qnil;
if (TYPE(v) != type) {
- conversion_mismatch(val, tname, RSTRING_PTR(rb_id2str(method)), v);
+ rb_cant_convert_invalid_return(val, tname, rb_id2name(method), v);
}
return v;
}
@@ -3284,7 +3402,7 @@ rb_to_integer_with_id_exception(VALUE val, const char *method, ID mid, int raise
return Qnil;
}
if (!RB_INTEGER_TYPE_P(v)) {
- conversion_mismatch(val, "Integer", method, v);
+ rb_cant_convert_invalid_return(val, "Integer", method, v);
}
GET_EC()->cfp = current_cfp;
return v;
@@ -3361,7 +3479,7 @@ rb_convert_to_integer(VALUE val, int base, int raise_exception)
}
else if (NIL_P(val)) {
if (!raise_exception) return Qnil;
- rb_raise(rb_eTypeError, "can't convert nil into Integer");
+ rb_cant_convert(val, "Integer");
}
tmp = rb_protect(rb_check_to_int, val, NULL);
@@ -3655,18 +3773,6 @@ rat2dbl_without_to_f(VALUE x)
}
/*! \endcond */
-static inline void
-conversion_to_float(VALUE val)
-{
- special_const_to_float(val, "can't convert ", " into Float");
-}
-
-static inline void
-implicit_conversion_to_float(VALUE val)
-{
- special_const_to_float(val, "no implicit conversion to float from ", "");
-}
-
static int
to_float(VALUE *valp, int raise_exception)
{
@@ -3680,7 +3786,7 @@ to_float(VALUE *valp, int raise_exception)
return T_FLOAT;
}
else if (raise_exception) {
- conversion_to_float(val);
+ rb_cant_convert(val, "Float");
}
}
else {
@@ -3760,8 +3866,7 @@ static VALUE
numeric_to_float(VALUE val)
{
if (!rb_obj_is_kind_of(val, rb_cNumeric)) {
- rb_raise(rb_eTypeError, "can't convert %"PRIsVALUE" into Float",
- rb_obj_class(val));
+ rb_cant_convert(val, "Float");
}
return rb_convert_type_with_id(val, T_FLOAT, "Float", id_to_f);
}
@@ -3805,7 +3910,7 @@ rb_num_to_dbl(VALUE val)
return rb_float_flonum_value(val);
}
else {
- conversion_to_float(val);
+ rb_cant_convert(val, "Float");
}
}
else {
@@ -3839,7 +3944,7 @@ rb_num2dbl(VALUE val)
return rb_float_flonum_value(val);
}
else {
- implicit_conversion_to_float(val);
+ rb_no_implicit_conversion(val, "Float");
}
}
else {
@@ -3851,7 +3956,7 @@ rb_num2dbl(VALUE val)
case T_RATIONAL:
return rat2dbl_without_to_f(val);
case T_STRING:
- rb_raise(rb_eTypeError, "no implicit conversion to float from string");
+ rb_no_implicit_conversion(val, "Float");
default:
break;
}
@@ -3945,7 +4050,7 @@ rb_Hash(VALUE val)
if (NIL_P(tmp)) {
if (RB_TYPE_P(val, T_ARRAY) && RARRAY_LEN(val) == 0)
return rb_hash_new();
- rb_raise(rb_eTypeError, "can't convert %s into Hash", rb_obj_classname(val));
+ rb_cant_convert(val, "Hash");
}
return tmp;
}
@@ -3966,7 +4071,7 @@ rb_Hash(VALUE val)
*
* Examples:
*
- * Hash({foo: 0, bar: 1}) # => {:foo=>0, :bar=>1}
+ * Hash({foo: 0, bar: 1}) # => {foo: 0, bar: 1}
* Hash(nil) # => {}
* Hash([]) # => {}
*
@@ -4053,7 +4158,7 @@ rb_obj_dig(int argc, VALUE *argv, VALUE obj, VALUE notfound)
* into +format_string+.
*
* For details on +format_string+, see
- * {Format Specifications}[rdoc-ref:format_specifications.rdoc].
+ * {Format Specifications}[rdoc-ref:language/format_specifications.rdoc].
*/
static VALUE
@@ -4218,8 +4323,8 @@ rb_f_loop_size(VALUE self, VALUE args, VALUE eobj)
*
* First, what's elsewhere. Class \Object:
*
- * - Inherits from {class BasicObject}[rdoc-ref:BasicObject@What-27s+Here].
- * - Includes {module Kernel}[rdoc-ref:Kernel@What-27s+Here].
+ * - Inherits from {class BasicObject}[rdoc-ref:BasicObject@Whats+Here].
+ * - Includes {module Kernel}[rdoc-ref:Kernel@Whats+Here].
*
* Here, class \Object provides methods for:
*
@@ -4313,7 +4418,6 @@ InitVM_Object(void)
#endif
rb_define_private_method(rb_cBasicObject, "initialize", rb_obj_initialize, 0);
- rb_define_alloc_func(rb_cBasicObject, rb_class_allocate_instance);
rb_define_method(rb_cBasicObject, "==", rb_obj_equal, 1);
rb_define_method(rb_cBasicObject, "equal?", rb_obj_equal, 1);
rb_define_method(rb_cBasicObject, "!", rb_obj_not, 0);
@@ -4494,6 +4598,7 @@ InitVM_Object(void)
rb_define_method(rb_mKernel, "to_s", rb_any_to_s, 0);
rb_define_method(rb_mKernel, "inspect", rb_obj_inspect, 0);
+ rb_define_private_method(rb_mKernel, "instance_variables_to_inspect", rb_obj_instance_variables_to_inspect, 0);
rb_define_method(rb_mKernel, "methods", rb_obj_methods, -1); /* in class.c */
rb_define_method(rb_mKernel, "singleton_methods", rb_obj_singleton_methods, -1); /* in class.c */
rb_define_method(rb_mKernel, "protected_methods", rb_obj_protected_methods, -1); /* in class.c */
@@ -4542,7 +4647,6 @@ InitVM_Object(void)
rb_define_method(rb_cModule, "<=", rb_class_inherited_p, 1);
rb_define_method(rb_cModule, ">", rb_mod_gt, 1);
rb_define_method(rb_cModule, ">=", rb_mod_ge, 1);
- rb_define_method(rb_cModule, "initialize_copy", rb_mod_init_copy, 1); /* in class.c */
rb_define_method(rb_cModule, "to_s", rb_mod_to_s, 0);
rb_define_alias(rb_cModule, "inspect", "to_s");
rb_define_method(rb_cModule, "included_modules", rb_mod_included_modules, 0); /* in class.c */