in reply to Re: "used only once" warning from Class::Std
in thread "used only once" warning from Class::Std

It makes sense that it would be a compile time warning and be issued only once for a given compilation. I had thought this initially but then was confused when I instrumented Class::Std. I changed Class::Std::DESTROY to (note the addition of print statements, no other changes):

sub DESTROY { my ($self) = @_; my $id = ID($self); push @_, $id; print "here we are in DESTROY\n"; DEMOLISH: for my $base_class (_hierarchy_of(ref $_[0])) { no strict 'refs'; print "destroying $base_class\n"; # no warnings 'once'; if (my $demolish_ref = *{$base_class.'::DEMOLISH'}{CODE}) { print "about to call destroy on $base_class\n"; &{$demolish_ref}; } for my $attr_ref ( @{$attribute{$base_class}} ) { delete $attr_ref->{ref}{$id}; } } }

Running my program against this modified version of Class::Std produces this:

here we are in DESTROY destroying MyClass Name "MyClass::DEMOLISH" used only once: possible typo at Class/Std.pm + line 528. here we are in DESTROY destroying MyClass

I suppose this comes down to an issue of which compile time. Since we are dealing with a symbolic reference, the value of which isn't known until runtime, the compilation, if there is such a thing for a symbolic reference, must be deferred until what is to be compiled is know.

To further test the idea that a compile time warning would be issued only once, I added another object to the module, as follows:

package MyClass; use strict; use warnings; use Class::Std; my $hash_ref = {}; bless $hash_ref, 'MyClass'; my $hash_ref2 = {}; bless $hash_ref2, 'MyClass'; 1;

And was surprised to see the following output - without any warning:

here we are in DESTROY destroying MyClass here we are in DESTROY destroying MyClass here we are in DESTROY destroying MyClass

The subroutine that only references the symbol once, but is called three times no longer causes a warning to be produced. Yet in the initial case, where it was called twice, it does cause a warning to be produced. I am now more puzzled than before. I suspect I have a fundamental misunderstanding of the scope over which use warnings qw(once); operates and what happens at compile time(s) Vs what happens at runtime. This would be nothing new.

And there is yet another issue. If i remove the blessing of the hash reference to MyClass:

package MyClass; use strict; use warnings; use Class::Std; my $hash_ref = {}; #bless $hash_ref, 'MyClass'; 1;

And run this against my modified version of Class::Std, I get the following output:

here we are in DESTROY destroying MyClass

Here we have the same subroutine passed the same base class, producing the same symbolic reference, yet no warning is produced.

So, it seems not to be a simple as a compile time warning being produced only once for one bit of code.

My (potentially mis-)understanding is that the sub DESTROY is defined and compiled once, when the Class::Std module is compiled. A reference to the sub is then added to the symbol table of MyClass, and it is executed one, two or three times, depending on which version of the test is run.

It is the bless $hash_ref, 'MyClass'; in MyClass that stimulates the warning, but only if it occurs only once - if it occurs twice, there is no warning. And calling DESTROY on the object created by the new method of MyClass, exported from Class::Std, does not cause a warning to be issued.