The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

More on globals; what to do in Perl & similal languages?

Thanks to all who replied to my earlier topic. The response was almost unanimous, to avoid using global variables at all cost, with few exceptions. My original inquiry was concerned with older procedural languages like C, but I'm kind of perplexed about what to do with scripting languages like Perl. In C, program execution starts inside a function (main()). I'm not going to go into detail describing the compilation and execution phases of the perl interpreter, but suffice to say, statements, declarations, and defintions can me mixed liberally as one sees fit. This has some interesting consequences. Considder the following:

#!/usr/bin/perl -w
use strict;
use LWP;

my $url = get_url();
do_something_to_url($url) or die some_error();
my $parsed_data = parse_something_from_url($url);
show_data($parsed_data);

sub get_url {
...
}

sub do_something_to_url {
...
}

... # and so on

In the above, $url and $parsed_data are lexically scoped (because they were declared with "my"), but their scope is the entire file (since they aren't within curly braces). Every function declared below can see them and modidify them. They have the effect of being global--at least within that source file--while their use is purly local.

What should I do here? I could wrap the code in braces, like this:

{
    my $url = get_url();
    do_something_to_url($url) or die some_error();
    my $parsed_data = parse_something_from_url($url);
    show_data($parsed_data);
}

or make it a sub, and call it right afterwards (you actualy have to do this if you're writing a mod_perl script with Apache::Registry):

sub main {
    my $url = get_url();
    do_something_to_url($url) or die some_error();
    my $parsed_data = parse_something_from_url($url);
    show_data($parsed_data);
}
main();

to make them local to that body of code. What would you guys suggest?
Globalist
Thursday, October 19, 2006
 
 
"can me mixed" -> "can be mixed"
"considder" -> "consider"
"modidify" -> "modify"
Globalist
Thursday, October 19, 2006
 
 
I generally use a main. But I also usually make configuration variables global though.
son of parnas
Thursday, October 19, 2006
 
 
Using a main is certainly safer.  That way you can be explicit about which variables are global and not accidentally reference non-globals in the subroutines.  I like to minimize the scope of the lexicals so I tend to use constructs like:
foreach my $val ( @list_of_vals )
Camel Jockey Send private email
Thursday, October 19, 2006
 
 
I always use a 'sub main()'.

I was taught this in Pascal, lo these many moons ago.  'C' FORCES you to have a 'main', that's what the 'runtime' calls once your program loads.

So it's no great stretch to have a 'sub main()' in a Perl script either.
AllanL5
Thursday, October 19, 2006
 
 
How about using them all as parameters.
If an error occurs then return null or empty string.

None of those temporary variables. Unless you want to do something twice to a temporary, but then you can do it twice inside some subroutine where the scoping is local.


show_data(
  parse_something_from_url(
    do_something_to_url(
        get_url()
    )
  )
)



PS. I wonder if this will be indented after I submit.
PPS. http://www.oreilly.com/pub/topic/perl where is the Perl Objects References and Modules book that I used to recomment.
or try ruby, I am
Thursday, October 19, 2006
 
 
The nested approach can be hard to debug -- there's nothing you can 'examine' to see where stuff went wrong.  And you STILL have 'temporary variable' there -- they're just handled by the compiler/runtime, not by you.
AllanL5
Thursday, October 19, 2006
 
 
> there's nothing you can 'examine'

Huh. Each subroutine can show you what has been passed to it.
same guy
Thursday, October 19, 2006
 
 
Learn modules as a minimum.

Package X

Package main

But you need to go to work to make sure people won't pollute things.

You don't need to use globals, and shouldn't and both PHP and Perl provide ways to easily not use them like always initialize and in php never use global.
curdDeveloper
Monday, October 23, 2006
 
 
Globalist,

What you essentially have in your example is a main function; making an explicit block out of it or declaring it as a subroutine doesn't change what it is.  If that block is meant to be your main program, there's no issue from what I can see.

That said, if there are any cases where that code shouldn't execute (example: other programs loading the file to use its subroutines), wrapping the code in a subroutine is appropriate.
Matt Brown
Wednesday, October 25, 2006
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz