shobhit has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I was looking at this node, and it started me on attributes in Perl. From there I moved on here.
Therefore, I thought that I would write my own .pm to use to log messages. Now I am not trying to reinvent the wheel here, but just learning how the wheel rotates. I have written a LogMessages.pm and a demoLogMessages.pl
LogMessages.pm. The _log function I borrowed from the perl.com aricle linked above.

package LogMessages; use strict; use warnings; use Attribute::Handlers; our @ISA=qw/Exporter/; use constant DEBUG => 1; our @EXPORT=qw/ _log /; sub new{ my $invocant=shift; my $class=ref($invocant) || $invocant; my $randomFileName=rand; print "Logging execution to $randomFileName\n"; my $self={ logfile=>$randomFileName, @_ # Override the default value. }; bless($self, $class); print "Logging execution to $self->{logfile}\n"; return $self; } sub getLogTime{ my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov De +c); my @weekDays = qw(Sun Mon Tue Wed Thu Fri Sat Sun); my ($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, + $dayOfWeek, $dayOfYear, $daylightSavings) = localtime(); my $year = 1900 + $yearOffset; my $time = "$hour:$minute:$second, $weekDays[$dayOfWeek] $mont +hs[$month] $dayOfMonth, $year"; return $time; } sub log_message{ my $self=shift; open(LOGFILE, ">>$self->{logfile}") or die "Cannot open logfil +e"; my $time=getLogTime(); print LOGFILE $time, " "; for (@_){ print LOGFILE @_; } } sub _log : ATTR(CODE) { # CODE means the attrib applie +s only to subroutines. my ($pkg, $sym, $code) = @_; # pkg in which the subroutine +was compiled. # reference to the typeglob wh +ere its symbol lives. # reference to subroutine itse +lf. if( DEBUG ) { my $name = *{ $sym }{NAME}; no warnings 'redefine'; # Turn off symbol redefinition +s within the block. *{ $sym } = sub { log_message("Entering sub $pkg\:\:$name\n"); my @ret = $code->( @_ ); log_message("Leaving sub $pkg\:\:$name\n"); return @ret; }; } }

demoLogMessages.pl
use strict; use warnings; use lib "/home/sho/perl/dev/"; use LogMessages; sub do_something : _log { print "I'm doing something.\n"; } do_something();
Running the script produces the following output.
Invalid CODE attribute: _log at ./demoLogMessages.pl line 6 BEGIN failed--compilation aborted at ./demoLogMessages.pl line 8.
Running it as perl -d is not much help either :-(
Invalid CODE attribute: _log at demoLogMessages.pl line 27 at /usr/lib/perl5/5.8.8/attributes.pm line 65 attributes::import('attributes', 'main', 'CODE(0x926b08c)', '_ +log') called at demoLogMessages.pl line 27 main::BEGIN() called at demoLogMessages.pl line 29 eval {...} called at demoLogMessages.pl line 29 BEGIN failed--compilation aborted at demoLogMessages.pl line 29. at demoLogMessages.pl line 29 Debugged program terminated. Use q to quit or R to restart,
What am I doing wrong here? I would be very grateful if someone could point me in the right direction. Thanks.

Replies are listed 'Best First'.
Re: Using an attribute function from a .pm file.
by shmem (Chancellor) on Aug 12, 2007 at 17:02 UTC
    If I add a line to your code...
    use strict; use warnings; use lib "/home/sho/perl/dev/"; use LogMessages; BEGIN { our @ISA = qw (LogMessages) } sub do_something : _log { print "I'm doing something.\n"; } do_something();

    ...it croaks

    Can't use string ("Entering sub main::do_something ") as a HASH ref while "strict refs" in use at LogMessages.pm line 42.

    42... that should keep you going :-)

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
    A reply falls below the community's threshold of quality. You may see it by logging in.