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

Hi, i am using perl from 1 year. But i am new to OOPS. I have a class used to write the log messages to the file

use Test_logger; my $log = Test_logger -> new();

There is a constructor which will create a unique log file. Ex : Feb_14_2008_15_30_30 ( Month_Day_Year_Hour_Min_Sec). I have a method called message to receive a scalar value and write the contents of scalar to the log file.

$log -> message (" Start of program");

This works fine. But i have a lot of my own modules in my main program. So when i call these subroutines i want to pass this log object to the subroutine so that the subroutine logs also can be visible. Hence i want to pass this object to the subroutine and write logs there. But This is not working.

Ex:

use ADDITION ( &test_addition); test_addition ( $log); sub test_addition { my $log = shift; $log -> message ("Inside the subroutine test_addition); } In my main program print $log ; gives HASH(0x1e2ec5c) in the subroutine print $log ; gives HASH(0x1e2ec5c)

20080215 Janitored by Corion: Added formatting, code tags, as per Writeup Formatting Tips

Replies are listed 'Best First'.
Re: how to pass object to a subroutine
by moritz (Cardinal) on Feb 14, 2008 at 10:29 UTC
    Use can use something like this:
    my $logger = sub { $log->message(@_); } # now you can call $logger like this: $logger->('This is a logging message'); # or like that: &$logger('This is a logging message');

    Don't know if that answers your question, though.

    Update: on second reading I think your problem is a different one: you want to print $log. But what do you want the output to be? An object doesn't have a nice default string representation.

Re: how to pass object to a subroutine
by johngg (Canon) on Feb 14, 2008 at 12:05 UTC
    If moritz's second reading is correct and you want to print a representation of your object then you could look at overload to associate a subroutine with stringification of your object. Something along the lines of

    use strict; use warnings; package MyModule; use overload q{""} => q{printObject}; sub new { ... } ... sub printObject { # print your attributes here } package main; my $obj = MyModule->new(some => q{args}); ... print qq{$obj}; ...

    I'm not sure either from your post whether this is what you want but here's hoping.

    Cheers,

    JohnGG

Re: how to pass object to a subroutine
by almut (Canon) on Feb 14, 2008 at 12:48 UTC
    ... print $log ; gives HASH(0x1e2ec5c)

    It should print "Test_logger=HASH(0x1e2ec5c)", i.e. the stringified representation of an object reference would normally include the package name.  The fact that it doesn't, in your case, makes me think that maybe you forgot to bless the hash in the constructor?

    Here's a simple example that should work the way (I think) you're expecting:

    ___ Test_logger.pm ___

    package Test_logger; sub new { my $pkg = shift; my $self = { logfile => "/tmp/test_logger.log", # default @_ # merge in user-specified attributes }; open my $fh, ">", $self->{logfile} or die "Cannot open logfile '$s +elf->{logfile}': $!"; $self->{logfh} = $fh; return bless $self, $pkg; } sub message { my $self = shift; my $msg = shift; my $fh = $self->{logfh}; print $fh "$msg\n"; } 1;

    ___ main program ___

    #!/usr/bin/perl use strict; use warnings; use Test_logger; sub test_addition { my $log = shift; $log->message("Inside the subroutine test_addition"); } my $log = Test_logger->new( logfile => "my.log" ); $log->message("Start of program"); test_addition($log);

    Of course, you can similarly pass $log to any subroutine defined in other modules as well...

Re: how to pass object to a subroutine
by cdarke (Prior) on Feb 14, 2008 at 12:45 UTC
    You don't show your constructor, but I guess that your are using bless on a reference to a hash. Therefore the print is correct, you are printing an object, which is a blessed reference to a hash. What is it that the subroutines expect as their argument? If a string then overload the " operator as described above, or maybe you should be using select to override the default output handle?