in reply to Problem Declaring Variable

First, I'd like to commend you for trying to figure out how to use strict. And, yes, the problem is one of scoping.

There are two solutions, one better than the other.

  1. Put a my $yesterday; outside of the if clause. Then, it's just $yesterday = &read_benchmark();. This is creating a global variable. Acceptable, but not very scalable.
  2. The better solution is to pass $yesterday into print_report(). You'd do it something like this:
    my $yesterday = &read_benchmark(); ... &print_report($yesterday); ... sub print_report { my ($yesterday) = @_; # Rest of function the same. }
    This is considered better because you could then re-use the print_report() function with some other script and it wouldn't depend on $yesterday being declared for it.

------
We are the carpenters and bricklayers of the Information Age.

Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Replies are listed 'Best First'.
Re: Re: Problem Declaring Variable
by derby (Abbot) on Mar 13, 2002 at 16:19 UTC

      definetly pass $yesterday to avoid demerphq's unintended global

      Well, if you have subs at the bottom and main code outside of a block, like this author has, ALL lexicals that aren't in a block, are semi-global. So you can avoid having this one as an "inintended global" by putting it in the if-block, but that still leaves all unblocked lexicals. In this stripped piece of code, that's only $today, but in larger programs the results can be disastrous.

      U28geW91IGNhbiBhbGwgcm90MTMgY
      W5kIHBhY2soKS4gQnV0IGRvIHlvdS
      ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
      geW91IHNlZSBpdD8gIC0tIEp1ZXJk
      

Re: Re: Problem Declaring Variable
by Juerd (Abbot) on Mar 13, 2002 at 16:49 UTC

    1. Put a my $yesterday; outside of the if clause. Then, it's just $yesterday = &read_benchmark();. This is creating a global variable. Acceptable, but not very scalable.

    That would issue a compile time error. You need to tell you're going to use the global first, with our or use vars. This can be avoided by just using my: the lexical scopes lasts till the end of the file, so the subs can access it. This behaviour is often unintended, and the results are indeed not very scalable. Because of that, I advise the author of the root node in this thread to put main code after the subs, to get them out of lexical scope.

    Update - It would not issue a compile time error, because it would not be a global at all. Instead, it'd be a lexical variable that lasts until the end of the file. This makes most of my original post untrue. However, it is imho still a bad idea to use globally used lexicals.

    U28geW91IGNhbiBhbGwgcm90MTMgY
    W5kIHBhY2soKS4gQnV0IGRvIHlvdS
    ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
    geW91IHNlZSBpdD8gIC0tIEp1ZXJk