in reply to Help - I'm a C programmer

You should always avoid globals at all costs; it's just bad programming in any language.

I'm not sure what you are trying to do with your code, but lets assuming that the function that you evaluate and manipulate your hash is "change_hash". "change_hash" should return a value, 1 if something changed, or 0 if no changes were made. With that in mind, your basic code should look something like this:

while ( change_hash( \%hash ) ) {}

Within change_hash, you appear to be looking at all the elements, so one way to write this as to return what you need is as follows:

sub change_hash { my $hashref = shift; my $returnflag = 0; foreach my $key ( keys %$hashref ) { if ( change_needed( $key, $$hashref{ $key } ) ) { $returnflag = 1; # do change here } } return $returnflag; }

Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain

Replies are listed 'Best First'.
Re: Re: Help - I'm a C programmer
by clintp (Curate) on Jun 17, 2001 at 19:59 UTC
    Excellent reply. Although I'd like to say that:
    You should always avoid globals at all costs; it's just bad programming in any language.
    Is wrongheadedness like most blanket statements in programming ("never use a goto!" "always enter loops at the top and exit at the bottom!" etc..).

    You should avoid globals<super>*</super> wherever possible, but not go through great pains and contortions to do so. Sometimes they're more appropriate than passing parameters to every function in a system to handle every possible need that may require them. For our C programmer, errno is an example where having a variable that has a "global" scope is much more appropriate than having every function which might do I/O receive it (or a pointer) as a parameter and pass it around during exception handling.

    <super>*</super>I'm including file-scoped lexicals and package variables in this category and not the ${special_character} variables. Those, for the most part, are evil.

      The thing about global variables is not the way they work; it's generally the problem with namespace collisions.

      There are times when you do need something similar to a global variable functionality; in languages where namespace collisions can be easily avoided, such as C++, Java, Perl, or the like, you should never define a global variable, instead creating one at an Object or Package scope. Unforunately, you can't do the same for C; the best you can do is create a special variable with a very descriptive name to act as a global, such that the chance for namespace collision is low. Even with something like errno, that ought to be stored away in some non-global area to prevent some third party code overwriting it unintentionally before you have a chance to use it.


      Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
        If you want to store away errno, you can.

        But if you want to do that then you probably wanted to use a variable other than errno.

        Remember that the purpose of errno ($! to Perl programmers) is to pass a very specific type of error information implicitly between code that otherwise knows little about each other. Having each library define its own little custom error reporting tool just results in turning error handling into such a mess that nobody will bother to do it.

        Now I agree with both telling beginning programmers the naive rule, and telling more experienced programmers the fact that it isn't always true. But for me the litmus test is simple. The question is, "Is this something that I want to have all of my code be aware of?" If I don't want to always be thinking of it, then it shouldn't be global. If I don't want to always be thinking of it within this package, then it shouldn't be a package global either.

        So as you see, I am not religious about saying, "NO GLOBALS". However I don't use very many of them...

        I use, for #define symbols that are horribly global, names based on UUID's (a.k.a. GUID's). That cannot match anyone else's generated UUID, and is quite unlikely to match a random string of hex digits that someone just pulled out of the air or generated with some other algorithm.

        —John

      I agree with clintp's comments about globals.

      For me, the amount of globals I use depends very much on the type of code I am writing. (See useful discussion on styles of code @ Why I like functional programming).

      For e.g. an object class, I would expect no globals to be used in the implementation.

      For e.g. an event loop (driven my user input), where you have large numbers of entry points into the code, you don't want to handle the passing of the state around everywhere, specially when the state gets large.

      The "globals" though should be carefully restricted to the smallest possible scope so that they don't pollute. It should be rare that the scope is "main", for any Packages in Perl.

      Taking the errno example, I took the view recently that it was better to hide the implementation of errors and provide an error() function that would provide the most recent error, rather than expose the implementation of errors within the package. Now I can change the implementation later without breaking existing user code.
      --
      Brovnik

        For e.g. an event loop (driven my user input), where you have large numbers of entry points into the code, you don't want to handle the passing of the state around everywhere, specially when the state gets large

        Was this an example of when to use globals? This is exactly when using globals will come back and bite you a couple weeks/months down the line. If you have a large and complex "state", wrap it up into a meaningful structure; Then you just have to pass around a reference to that structure, which makes passing around a large state very easy.

Re: Re: Help - I'm a C programmer
by june_bo (Novice) on Jun 18, 2001 at 00:42 UTC
    Would you point me in the right direction to understand the %$ and the $$? I looked in my "Programming Perl" book but didn't find anything.

    Thanks,
    tl

      The %$hashref construct is just a shortcut for %{ $hashref }. $$hashref{$key} is similar, just takes a single value from hash.

      -mk