Feature #16129 ยป initialize-clone-freeze-false.patch
lib/delegate.rb | ||
---|---|---|
end
|
||
end
|
||
def initialize_clone(obj) # :nodoc:
|
||
self.__setobj__(obj.__getobj__.clone)
|
||
def initialize_clone(obj, freeze: true) # :nodoc:
|
||
self.__setobj__(obj.__getobj__.clone(freeze: freeze))
|
||
end
|
||
def initialize_dup(obj) # :nodoc:
|
||
self.__setobj__(obj.__getobj__.dup)
|
lib/set.rb | ||
---|---|---|
end
|
||
# Clone internal hash.
|
||
def initialize_clone(orig)
|
||
def initialize_clone(orig, freeze: true)
|
||
super
|
||
@hash = orig.instance_variable_get(:@hash).clone
|
||
@hash = orig.instance_variable_get(:@hash).clone(freeze: freeze)
|
||
end
|
||
def freeze # :nodoc:
|
object.c | ||
---|---|---|
}
|
||
init_copy(clone, obj);
|
||
rb_funcall(clone, id_init_clone, 1, obj);
|
||
if (kwfreeze) {
|
||
rb_funcall(clone, id_init_clone, 1, obj);
|
||
RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE;
|
||
}
|
||
else {
|
||
static VALUE freeze_false_hash;
|
||
if (!freeze_false_hash) {
|
||
freeze_false_hash = rb_hash_new();
|
||
rb_hash_aset(freeze_false_hash, ID2SYM(rb_intern("freeze")), Qfalse);
|
||
rb_obj_freeze(freeze_false_hash);
|
||
rb_gc_register_mark_object(freeze_false_hash);
|
||
}
|
||
rb_funcall(clone, id_init_clone, 2, obj, freeze_false_hash);
|
||
}
|
||
return clone;
|
||
}
|
||
... | ... | |
/*!
|
||
* :nodoc:
|
||
*--
|
||
* Default implementation of \c #initialize_dup and \c #initialize_clone
|
||
* Default implementation of \c #initialize_dup
|
||
*
|
||
* \param[in,out] obj the receiver being initialized
|
||
* \param[in] orig the object to be dup or cloned from.
|
||
* \param[in] orig the object to be dup from.
|
||
*++
|
||
**/
|
||
VALUE
|
||
... | ... | |
return obj;
|
||
}
|
||
/*!
|
||
* :nodoc:
|
||
*--
|
||
* Default implementation of \c #initialize_clone
|
||
*
|
||
* \param[in,out] obj the receiver being initialized
|
||
* \param[in] orig the object to be cloned from.
|
||
*++
|
||
**/
|
||
static VALUE
|
||
rb_obj_init_clone(int argc, VALUE *argv, VALUE obj)
|
||
{
|
||
VALUE orig, opts;
|
||
rb_scan_args(argc, argv, "1:", &orig, &opts);
|
||
/* Ignore a freeze keyword */
|
||
if (argc == 2) (void)freeze_opt(1, &opts);
|
||
rb_funcall(obj, id_init_copy, 1, orig);
|
||
return obj;
|
||
}
|
||
/**
|
||
* call-seq:
|
||
* obj.to_s -> string
|
||
... | ... | |
/* :nodoc: */
|
||
static VALUE
|
||
rb_mod_initialize_clone(VALUE clone, VALUE orig)
|
||
rb_mod_initialize_clone(int argc, VALUE* argv, VALUE clone)
|
||
{
|
||
VALUE ret;
|
||
ret = rb_obj_init_dup_clone(clone, orig);
|
||
VALUE ret, orig, opts;
|
||
rb_scan_args(argc, argv, "1:", &orig, &opts);
|
||
ret = rb_obj_init_clone(argc, argv, clone);
|
||
if (OBJ_FROZEN(orig))
|
||
rb_class_name(clone);
|
||
return ret;
|
||
... | ... | |
rb_define_method(rb_mKernel, "then", rb_obj_yield_self, 0);
|
||
rb_define_method(rb_mKernel, "initialize_copy", rb_obj_init_copy, 1);
|
||
rb_define_method(rb_mKernel, "initialize_dup", rb_obj_init_dup_clone, 1);
|
||
rb_define_method(rb_mKernel, "initialize_clone", rb_obj_init_dup_clone, 1);
|
||
rb_define_method(rb_mKernel, "initialize_clone", rb_obj_init_clone, -1);
|
||
rb_define_method(rb_mKernel, "taint", rb_obj_taint, 0);
|
||
rb_define_method(rb_mKernel, "tainted?", rb_obj_tainted, 0);
|
||
... | ... | |
rb_define_alloc_func(rb_cModule, rb_module_s_alloc);
|
||
rb_define_method(rb_cModule, "initialize", rb_mod_initialize, 0);
|
||
rb_define_method(rb_cModule, "initialize_clone", rb_mod_initialize_clone, 1);
|
||
rb_define_method(rb_cModule, "initialize_clone", rb_mod_initialize_clone, -1);
|
||
rb_define_method(rb_cModule, "instance_methods", rb_class_instance_methods, -1); /* in class.c */
|
||
rb_define_method(rb_cModule, "public_instance_methods",
|
||
rb_class_public_instance_methods, -1); /* in class.c */
|
test/ruby/test_module.rb | ||
---|---|---|
assert_equal :M2, CloneTestC2.new.foo, '[Bug #15877]'
|
||
end
|
||
def test_clone_freeze
|
||
m = Module.new.freeze
|
||
assert_predicate m.clone, :frozen?
|
||
assert_not_predicate m.clone(freeze: false), :frozen?
|
||
end
|
||
private
|
||
def assert_top_method_is_private(method)
|
test/ruby/test_object.rb | ||
---|---|---|
assert_raise_with_message(ArgumentError, /\u{1f4a9}/) do
|
||
Object.new.clone(freeze: x)
|
||
end
|
||
c = Class.new do
|
||
attr_reader :f
|
||
end
|
||
o = c.new
|
||
f = true
|
||
def o.initialize_clone(_, freeze: true)
|
||
@f = freeze
|
||
super
|
||
end
|
||
clone = o.clone
|
||
assert_kind_of c, clone
|
||
assert_equal true, clone.f
|
||
clone = o.clone(freeze: false)
|
||
assert_kind_of c, clone
|
||
assert_equal false, clone.f
|
||
def o.initialize_clone(_)
|
||
super
|
||
end
|
||
assert_kind_of c, o.clone
|
||
assert_raise(ArgumentError) { o.clone(freeze: false) }
|
||
end
|
||
def test_init_dupclone
|
test/test_delegate.rb | ||
---|---|---|
assert_equal(SimpleDelegator,simple.clone.class)
|
||
end
|
||
def test_simpledelegator_clone
|
||
simple=SimpleDelegator.new([])
|
||
simple.freeze
|
||
clone = simple.clone
|
||
assert_predicate clone, :frozen?
|
||
assert_predicate clone.__getobj__, :frozen?
|
||
assert_equal true, Kernel.instance_method(:frozen?).bind(clone).call
|
||
clone = simple.clone(freeze: false)
|
||
assert_not_predicate clone, :frozen?
|
||
assert_not_predicate clone.__getobj__, :frozen?
|
||
assert_equal false, Kernel.instance_method(:frozen?).bind(clone).call
|
||
end
|
||
class Object
|
||
def m
|
||
:o
|
test/test_set.rb | ||
---|---|---|
}
|
||
end
|
||
def test_freeze_clone_false
|
||
set1 = Set[1,2,3]
|
||
set1.freeze
|
||
set2 = set1.clone(freeze: false)
|
||
assert_not_predicate set2, :frozen?
|
||
set2.add 5
|
||
assert_equal Set[1,2,3,5], set2
|
||
assert_equal Set[1,2,3], set1
|
||
end
|
||
def test_inspect
|
||
set1 = Set[1, 2]
|
||
assert_equal('#<Set: {1, 2}>', set1.inspect)
|