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

Well I commented out the use strict.
What for?
(Though I would like to fix it and use strict. But let us move past this for now.)

No we won't, because the stricture warning gives you a clue about what's happening. You are using something as a hash ref which isn't, at line 42, which reads

open(LOGFILE, ">>$self->{logfile}") or die "Cannot open logfile";

See the hash ref in there, which isn't? You are dying at that line with an unappropriate message. Stick the filename you are trying to open in there, and $! to get the reason why something might go wrong.

Rewriting your sub log_message

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

I get

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

You are invoking log_message as a function inside your handler sub created in sub _log

*{ $sym } = sub { log_message("Entering sub $pkg\:\:$name\n"); my @ret = $code->( @_ ); log_message("Leaving sub $pkg\:\:$name\n"); return @ret; };

and perl is just doing what you tell it to do...

--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}

Replies are listed 'Best First'.
Re^4: Using an attribute function from a .pm file.
by shobhit (Sexton) on Aug 12, 2007 at 18:26 UTC
    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?
      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.