Clone-Closure
view release on metacpan or search on metacpan
lib/Clone/Closure.pm view on Meta::CPAN
=item *
weakrefs
Beware cloning weakrefs: cloning a reference also clones the object it
refers to, and if there are no strong refs to this new object it will
self-destruct before C<clone> returns. For example,
my $sv = 5;
my $ref = \$sv;
weaken $ref;
my $clone = clone $ref;
will result in $clone being C<undef>, as the new clone of $sv has no
(strong) referents. As weakrefs are normally used to break loops in
self-referential structures, this should not happen often.
=item *
custom magic (C<U>, C<u>, and C<~> magics)
lib/Clone/Closure.xs view on Meta::CPAN
#ifndef CvWEAKOUTSIDE_on
{
CV *old = CvOUTSIDE(new_sv);
SvREFCNT_dec(old);
TRACE_SV("ref", "outside", old);
}
#endif
CvOUTSIDE(new_sv) = clone;
#ifdef CvWEAKOUTSIDE_on
TRACE_SV("weaken", name, new_sv);
TRACE_SV("outside", name, clone);
CvWEAKOUTSIDE_on(new_sv);
#else
SvREFCNT_inc(clone);
TRACE_SV("clone", "outside", clone);
#endif
pad_clone(SEEN, (CV *)val_sv, (CV *)new_sv);
}
else if (can_copy) {
lib/Clone/Closure.xs view on Meta::CPAN
TRACE_SV("ref", "RV", ref);
SvROK_on(clone);
SvRV(clone) = sv_clone(SEEN, SvRV(ref));
if (sv_isobject(ref)) {
sv_bless(clone, SvSTASH(SvRV(ref)));
}
if (SvWEAKREF(ref)) {
TRACE_SV("weaken", "RV", clone);
sv_rvweaken(clone);
}
TRACE_SV("clone", "RV", clone);
}
if (SvREADONLY(ref))
SvREADONLY_on(clone);
TRACE_SV("clone", "SV", clone);
return clone;
sv_pvutf8n_force||5.006000|
sv_pvutf8n||5.006000|
sv_pvutf8||5.006000|
sv_pv||5.006000|
sv_recode_to_utf8||5.007003|
sv_reftype|||
sv_release_COW|||
sv_replace|||
sv_report_used|||
sv_reset|||
sv_rvweaken||5.006000|
sv_setiv_mg|5.004050||p
sv_setiv|||
sv_setnv_mg|5.006000||p
sv_setnv|||
sv_setpv_mg|5.004050||p
sv_setpvf_mg_nocontext|||pvn
sv_setpvf_mg|5.006000|5.004000|pv
sv_setpvf_nocontext|||vn
sv_setpvf||5.004000|v
sv_setpviv_mg||5.008001|
is $$mg, pos($str), '...but keeps value';
$$mg = 0;
is pos($str), 3, 'pos() preserved';
}
#define PERL_MAGIC_backref '<' /* for weak ref data */
SKIP: {
my $skip;
eval 'use Scalar::Util qw/weaken isweak/; 1'
or skip 'no weakrefs', $skip;
{
BEGIN { $skip += 5 }
# we need to have a real ref to the referent in the cloned
# structure, otherwise it destructs.
my $sv = 5;
my $weak = [\$sv, \$sv];
weaken($weak->[0]);
my $type = blessed b \$weak->[0];
my $rv = clone $weak;
isa_ok b(\$rv->[0]), $type, 'weakref cloned';
ok b(\$rv->[0])->ROK, '...and a reference';
ok isweak($rv->[0]), '...preserving isweak';
isnt $rv->[0], \$sv, '...not copied';
is ${$rv->[0]}, 5, '...correctly';
}
{
BEGIN { $skip += 6 }
my $weak = [5, undef];
$weak->[1] = \$weak->[0];
weaken($weak->[1]);
my $type = blessed b \$weak->[0];
my $rv = clone $weak;
isa_ok b(\$rv->[0]), $type, 'weak referent cloned';
isnt \$rv->[0], \$weak->[0], '...not copied';
ok isweak($rv->[1]), '...preserving isweak';
has_mg \$weak->[0], '<', '(sanity check)';
has_mg \$rv->[0], '<', '...with magic';
is $rv->[0], 5, '...correctly';
}
{
BEGIN { $skip += 8 }
my $circ;
$circ = \$circ;
weaken($circ);
my $type = blessed b \$circ;
my $rv = clone \$circ;
isa_ok b($rv), $type, 'weak circular ref cloned';
ok b(\$rv)->ROK, '...and a reference';
ok b($rv)->ROK, '...to a reference';
has_mg \$circ, '<', '(sanity check)';
has_mg $rv, '<', '...with magic';
ok isweak($$rv), '...preserving isweak';
isnt $$rv, \$circ, '...not copied';
t/07magic.t view on Meta::CPAN
use warnings;
use Test::More;
use Data::Dumper;
use Clone::Closure qw/clone/;
my $tests;
BEGIN { $tests += 1 }
SKIP: {
eval "use Scalar::Util qw( weaken ); 1";
skip "Scalar::Util not installed", 1 if $@;
my $x = { a => "worked\n" };
my $y = $x;
weaken($y);
my $z = clone $x;
is Dumper($x), Dumper($z), 'cloned weak reference';
}
## RT 21859: Clone::Closure segfault (isolated example)
BEGIN { $tests += 1 }
SKIP: {
my $string = "HDDR-WD-250JS";
eval {
use utf8;
( run in 0.269 second using v1.01-cache-2.11-cpan-a9ef4e587e4 )