in reply to Re^3: Using an attribute function from a .pm file.
in thread Using an attribute function from a .pm file.

I removed use strict because of the error message:
Can't use string ("Entering sub main::do_something ") as a HASH ref while "strict refs" in use at /home/sho/perl/dev//Log +Messages.pm line 43.
Thats not a good thing to do, and not an excuse to do it at all.

So now the problem is that in sub log_message my $self actually contains the string "Entering sub main::do_something\n". I believe that my
41 $self=shift
should put the class name in $self. I am referring to what I learnt here: A simple example OO script for total beginners.
Maybe my understanding of the concept is wrong.

Now how do I get the hash value of $self->{logfile} from sub log_message?

Replies are listed 'Best First'.
Re^5: Using an attribute function from a .pm file.
by shmem (Chancellor) on Aug 12, 2007 at 19:08 UTC
    I believe that my
    41 $self=shift
    should put the class name in $self.

    No - shift (defaults to shift @_) removes the first argument to the subroutine from its argument list (that's @_) and returns it; that's what you are storing into the variable $self. No voodoo here. Saying $self and shift doesn't make an object. The first argument to that subroutine is the string "Entering sub $pkg\:\:$name\n".

    Now how do I get the hash value of $self->{logfile} from sub log_message?
    Were $self a hash actually, and had it a key 'logfile' in it, you would get it from there.

    A previous ocurrence of that key is in your sub new in LogMessages.pm, but you don't make use of that method. It doesn't make much sense anyways, since all you want is the logfile name, not an object to pass around. So I'd pass that file name when use-ing LogMessages

    use LogMessages qw(/path/to/logfile);

    to store that into a lexical hash for the invoking package, in the import() subroutine of LogMessages :

    my %logfile; sub import { my $class = shift; $logfile{ +caller} = @_ ? shift : "/tmp/logfile.$$"; };

    Then you get the logfile stored for the using package from the lexical hash:

    sub _log : ATTR(CODE) { my ($pkg, $sym, $code) = @_; if ( DEBUG ) { my $name = *{ $sym }{NAME}; no warnings 'redefine'; # Turn off symbol redefinitions within + the block. *{ $sym } = sub { log_message ($logfile{$pkg}, "Entering sub $pkg\:\:$name\n +"); my @ret = $code->( @_ ); log_message ($logfile{$pkg}, "Leaving sub $pkg\:\:$name\n" +); return @ret; }; } }

    and then you have the logfile as first argument in the logging sub:

    sub log_message { my $logfile = shift; open my $LOGFILE, '>>', $logfile or die "Cannot open logfile '$logfile': $!"; my $time = getLogTime(); print $LOGFILE $time, " "; for (@_){ print $LOGFILE @_; } }

    Note three argument open and lexical filehandle. Don't forget to put a 1; at the end of your LogMessages.pm ...

    You are using @EXPORT and are stuffing Exporter into @ISA, but there's nowhere you do use Exporter in LogMessages. You don't need it, either, since you have nothing to export.

    --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}
      This looks like I went off completely on a tangent.
      Bitten off more than I could chew.

      Well, let me get my teeth around it and gnaw it and digest it. :-)

      Thanks for following this up all along.