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.


In reply to Re^2: "used only once" warning from Class::Std by ig
in thread "used only once" warning from Class::Std by ig

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.