Project

General

Profile

Feature #16129 ยป initialize-clone-freeze-false.patch

jeremyevans0 (Jeremy Evans), 08/26/2019 04:20 AM

View differences:

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)
    (1-1/1)