Global variables considered harmful?

D

darren kirby

--nextPart52506328.PINYBkrvoZ
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Hello all,

I have a Ruby script here that acts like a regular Unix program, including=
=20
accepting a large number of command-line options/arguments. After processin=
g=20
some are simple flags (ie: nil or 1) and some are text/numeric arguments.=
=20
Not all are required, and some must be initialized with a default value. I=
=20
have currently implemented them as globals, as their values are needed=20
anywhere in my script, from classes to functions to top-level flow control=
=20
code...

Now I know you are not supposed to rely on globals if you can help it, so I=
am=20
trying to rewrite my script to do away with them. The problem is that there=
=20
are so many command-line switches that simply passing them to the=20
class/function(s) that need them would be unwieldy.

So what do I do? I was thinking of creating and populating a new class that=
=20
would act similar to a C 'struct', but it seems to me that this is just a=20
different way to do the exact same thing as I have now, except that I would=
=20
have to qualify the variable with a class instance making my script even mo=
re=20
verbose than it is now...so why shouldn't we use globals again? Is it simpl=
y=20
the namespace issue or are there other reasons?=20

Is one global hash better than 15 global scalars?

I am not going to list my code here because it is 500+ lines but if you wan=
t=20
to see it let me know and I will post it to the web,

Thanks for consideration,
=2Dd=20
=2D-=20
darren kirby :: Part of the problem since 1976 :: http://badcomputer.org
"...the number of UNIX installations has grown to 10, with more expected..."
=2D Dennis Ritchie and Ken Thompson, June 1972

--nextPart52506328.PINYBkrvoZ
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.4 (GNU/Linux)

iD8DBQBE2OZxwPD5Cr/3CJgRAhAAAKCfiAggfsqQQNbjCnRQNt2AL7KffgCggRUU
3A3mGBuXoOGAM7/EoeNpSjE=
=utuP
-----END PGP SIGNATURE-----

--nextPart52506328.PINYBkrvoZ--
 
F

Francis Cianfrocca

Hello all,

I have a Ruby script here that acts like a regular Unix program, including
accepting a large number of command-line options/arguments. After processing
some are simple flags (ie: nil or 1) and some are text/numeric arguments.
Not all are required, and some must be initialized with a default value. I
have currently implemented them as globals, as their values are needed
anywhere in my script, from classes to functions to top-level flow control
code...

Now I know you are not supposed to rely on globals if you can help it, so I am
trying to rewrite my script to do away with them. The problem is that there
are so many command-line switches that simply passing them to the
class/function(s) that need them would be unwieldy.

So what do I do? I was thinking of creating and populating a new class that
would act similar to a C 'struct', but it seems to me that this is just a
different way to do the exact same thing as I have now, except that I would
have to qualify the variable with a class instance making my script even more
verbose than it is now...so why shouldn't we use globals again? Is it simply
the namespace issue or are there other reasons?

Is one global hash better than 15 global scalars?

I am not going to list my code here because it is 500+ lines but if you want
to see it let me know and I will post it to the web,

Thanks for consideration,
-d

Look at optparse for a better way to do command line arguments. Look
at OpenStruct for a better way to pass them around your program.
 
J

James Edward Gray II

Look at optparse for a better way to do command line arguments. Look
at OpenStruct for a better way to pass them around your program.

I imagine a plain Struct is sufficient here, since all of the values
are known before the code even runs.

James Edward Gray II
 
C

coachhilton

darren said:
Hello all,

I have a Ruby script here that acts like a regular Unix program, including
accepting a large number of command-line options/arguments. After processing
some are simple flags (ie: nil or 1) and some are text/numeric arguments.
Not all are required, and some must be initialized with a default value. I
have currently implemented them as globals, as their values are needed
anywhere in my script, from classes to functions to top-level flow control
code...

Now I know you are not supposed to rely on globals if you can help it, so I am
trying to rewrite my script to do away with them. The problem is that there
are so many command-line switches that simply passing them to the
class/function(s) that need them would be unwieldy.

So what do I do? I was thinking of creating and populating a new class that
would act similar to a C 'struct', but it seems to me that this is just a
different way to do the exact same thing as I have now, except that I would
have to qualify the variable with a class instance making my script even more
verbose than it is now...so why shouldn't we use globals again? Is it simply
the namespace issue or are there other reasons?

Is one global hash better than 15 global scalars?

I am not going to list my code here because it is 500+ lines but if you want
to see it let me know and I will post it to the web,

Thanks for consideration,
-d
Well, this is quite a "can of worms" topic, now isn't it? For whatever
its worth, here's what I do: I have a base class I've been working on
over time from which I derive all of my other scripts. In this base
class I have all of the logic to configure the script, from command
line options, to environment vars to config files along with a bunch of
handy helper methods for things like logging and debugging. The
results of the configuration go into member variables of this base
class, or optionally a hash of properties, and thereby form the context
in which the actual script/application runs. Sure, these are really
global variables packaged up in the base class but at least they are
encapsulate and the script doesn't know where they came from or how
they got there. This has worked pretty well for me over time for a
variety of program sizes.

Now then, the direction I've been heading in lately has been toward
"inversion of control" (see
http://martinfowler.com/articles/injection.html for a very nice
presentation of the topic.) I envision going to a Dependency Injection
pattern some time soon in which the configuration information is
obtained from an inversion control container, as described by Fowler.
But I think I'd only go to this level of "complexity" for true
applications and not for hundren line "scripts".

Hope this helps.

Ken
 
D

darren kirby

--nextPart1160735.9pGsJP0WdQ
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

quoth the Francis Cianfrocca:
On 8/8/06, darren kirby <[email protected]> wrote:
Look at optparse for a better way to do command line arguments. Look
at OpenStruct for a better way to pass them around your program.

Hi,

I am already using getOptLong to parse the command line and it works fine, =
are=20
you saying that optparse is preferable here?

In any event, using a plain or open struct seems like a better way to go th=
an=20
using a class.

Thanks guys,
=2Dd
=2D-=20
darren kirby :: Part of the problem since 1976 :: http://badcomputer.org
"...the number of UNIX installations has grown to 10, with more expected..."
=2D Dennis Ritchie and Ken Thompson, June 1972

--nextPart1160735.9pGsJP0WdQ
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.4 (GNU/Linux)

iD8DBQBE2O28wPD5Cr/3CJgRAl7kAJsGYtxI+MTeaH2SxI6oVErpjGVSRQCffaTA
3595YGsQCvZTxyCvI6STFhI=
=11JG
-----END PGP SIGNATURE-----

--nextPart1160735.9pGsJP0WdQ--
 
D

darren kirby

--nextPart1167735.9XiD6iYXY2
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

quoth the (e-mail address removed):
Well, this is quite a "can of worms" topic, now isn't it? =20

He, well, I certainly didn't intend for it, I am simply a self-taught=20
programmer who lacking a formal education tries to muddle through and pick =
up=20
some sage advice from here and there when possible...
For whatever=20
its worth, here's what I do: I have a base class I've been working on
over time from which I derive all of my other scripts. In this base
class I have all of the logic to configure the script, from command
line options, to environment vars to config files along with a bunch of
handy helper methods for things like logging and debugging. The
results of the configuration go into member variables of this base
class, or optionally a hash of properties, and thereby form the context
in which the actual script/application runs. Sure, these are really
global variables packaged up in the base class but at least they are
encapsulate and the script doesn't know where they came from or how
they got there. =20
This has worked pretty well for me over time for a=20
variety of program sizes.

Now then, the direction I've been heading in lately has been toward
"inversion of control" (see
http://martinfowler.com/articles/injection.html for a very nice
presentation of the topic.) I envision going to a Dependency Injection
pattern some time soon in which the configuration information is
obtained from an inversion control container, as described by Fowler.
But I think I'd only go to this level of "complexity" for true
applications and not for hundren line "scripts".

Hmm, that link you posted was a little over my head. I understand the conce=
pts=20
presented on the "inversion of control" page, but that is about it...
Hope this helps.

As I was basically just fishing for ideas, sure it did, thanks!

=2Dd
=2D-=20
darren kirby :: Part of the problem since 1976 :: http://badcomputer.org
"...the number of UNIX installations has grown to 10, with more expected..."
=2D Dennis Ritchie and Ken Thompson, June 1972

--nextPart1167735.9XiD6iYXY2
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.4 (GNU/Linux)

iD8DBQBE2PAUwPD5Cr/3CJgRAnUoAJ4yNFp6MRL5hNPw9TgzfVANp8ALPwCffvCR
3rXXJjowj2vijYIKiSQdDmg=
=SYgm
-----END PGP SIGNATURE-----

--nextPart1167735.9XiD6iYXY2--
 
J

James Edward Gray II

Sure, these are really
global variables packaged up in the base class but at least they are
encapsulate and the script doesn't know where they came from or how
they got there.

You can also make the class a singleton so all code works with just
one configuration object:
1651794
=> nil?> p Config.instance.object_id
1651794
=> nil

James Edward Gray II
 
J

John Carter

I have a Ruby script here that acts like a regular Unix program, including
accepting a large number of command-line options/arguments. After processing
some are simple flags (ie: nil or 1) and some are text/numeric arguments.
Not all are required, and some must be initialized with a default value. I
have currently implemented them as globals, as their values are needed
anywhere in my script, from classes to functions to top-level flow control
code...

I tend to parcel such things up into a Context object. Sort of like...

class MyProgContext

def initialize( argv)
parse_args( argv)
sanity_check
end

def print_help_and_exit( plain="Usage:-")
puts "
#{plaint}

myprog [options] arg1 arg2

Description

"
exit( 1)
end

end

context = MyProgContext.new( ARGV)

....

Advantages :-
* Collects all the stuff neatly into a class.
* Allows me to enforce invariants (ie. sanity check options / arguments for
mutual compatibility / sanity.
* Easy to unit test the ARGV parsing logic.





John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : (e-mail address removed)
New Zealand

Carter's Clarification of Murphy's Law.

"Things only ever go right so that they may go more spectacularly wrong later."

From this principle, all of life and physics may be deduced.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top