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

Hi all,
I'm trying to bless a hash so that the data may be accessed easier basically. If I try to print the value of the hash, nothing prints.
package Site::Cfg; # Stolen from Thomas Sibley's Mooseboard # <trs@perlmonk.org> sub new { my $class = shift; my $self = bless { template => \%templates }, $class; return $self; } my %templates = ( splash => 'C:/indigoperl/apache/fd/tmpl/splash.tmpl' + ); 1; ############################### #!perl -w use strict; use lib '.'; use Site; my $q = CGI->new; my $tmpl = Site::Cfg->new; print Site::Page->header; print $tmpl->{template}->{splash};
Any ideas?


dhoss
"and I wonder, when I sing along with you if everything could ever feel this real forever? if anything could ever be this good again? the only thing I'll ever ask of you, you've gotta promise not to stop when I say 'when'", she sang

Replies are listed 'Best First'.
Re: blessing a hash ref?
by flyingmoose (Priest) on Mar 19, 2004 at 00:53 UTC
    You are redeclaring a lexically scoped variable to override a package scoped variable. This is complicated, and I've already rewritten my post about 3 4 times to sort it out:)

    Essentially the two %templates variables you have aren't the same -- you are referencing one and obliterating it by replacing it with another. If you move the my above the subroutine definition, this works, and this is the cleanest way to do it I know of, as %templates has some assigned value when you use it -- and thus my will not be stomping over your old work by redefining an existing variable later on.

    our creates global variables (and mysteriously allows the post-assignment to work -- which in theory it should not if it was a top-down compile), but don't use our since globals are often evil. Always declaring with my is a very safe bet, especially if you do it towards the top of your function and/or package like you were coding to an anal C compiler.

    Using strict inside that top package would have made this more clear that your variable wasn't well defined. Somewhat more clear, anyway. It's a good reason to use strict.

    There is also a decent article that a lot of Monks mention, that you might want to read: Coping With Scoping.

    I'm looking forward to Perl6's more object-like syntax, so hopefully this will simplify itself. One can hope.

Re: blessing a hash ref?
by tedrek (Pilgrim) on Mar 19, 2004 at 01:00 UTC

    When you bless the new hash into Site::Cfg you give it a reference to the package variable %templates. This is because %templates hasn't yet been declared lexical. To fix it move my %templates... above the sub. use strict would have caught it.

    I tried to swear at perl and it compiled!
Re: blessing a hash ref?
by TomDLux (Vicar) on Mar 19, 2004 at 02:04 UTC

    You've done well in simplifying the problem to a short set which duplicates the fault, but I get the impression you are sticking with print statements, and avoiding your debugger.

    I would suggest tracing the code into the constructor, and exploring what $self contains just before the return. What does $tmpl contain after you return from the module?

    P.S. You have 'use strict' in your main script, but not where you need it, in the module.

    --
    TTTATCGGTCGTTATATAGATGTTTGCA

      P.S. You have 'use strict' in your main script, but not where you need it, in the module.

      Once you declare 'use strict', anywhere, everything else is compiled under strict from that point on, to the end of the enclosing block. In this case, its to late, because the compilation of the module has already happened.

      One day I'd like to see Perl's default behaviour be as per my sig...

      +++++++++++++++++
      #!/usr/bin/perl
      use warnings;use strict;use brain;

      Fair point, but this is one many of us are guilty of -- and I think that is ok. First of, the Perl debugger isn't the most friendly tool in the world. Secondly, coming from many environments when attaching a debugger is not going to help much (say, an unfamilar OS such as Netware, web interfaces, or debugging the C code being loaded by a java JNI process), it is not to say that debug-by-print-statement is sin. It is this second reason that I have grown not to rely on debuggers and IDE's. Usually, I can't depend on them. I depend on runtime error checking most of the time -- and debug-by-print when things get hairy (which is not often). Plus sometimes using a debugger means your brain isn't really rapped around the code. I've been around folks who say "I need a debugger" -- but I've really learned to read code for flaws (even without prints). Using 10 different platforms and 3 or 4 different languages at work makes you do that.

      In many places, debuggers are heavy hammers to wield, and print statements serve their quick-and-dirty place. In more sophisticated ways, you can write less-dirty debugger modules that can route their output to log files and such MyDebug::debug(-level => 4, -msg => "AllYourBase"), which is something like what log4perl does, though I've never used it -- crafting my own simpler hooks was easy enough.

      Didn't Larry himself say he didn't use the debugger much?

      update: just reading random monks home nodes (I should be watching basketball -- go AirForce! Beat UNC!), I came across this interesting commentary on debuggers. It drives home a few of my points, or at least gives me the assurance that I am not alone.

      I actually have strict where that code resides, I just cut out that sub, and excluded strict, but it's in the real script, trust me.

      dhoss
      "and I wonder, when I sing along with you if everything could ever feel this real forever? if anything could ever be this good again? the only thing I'll ever ask of you, you've gotta promise not to stop when I say 'when'", she sang