# Global variables considered harmful?

**URL:** <https://www.ruby-forum.com/t/global-variables-considered-harmful/101953>\
**Category:** Ruby\
**Created:** [August 8, 2006, 9:33pm UTC](https://www.ruby-forum.com/t/global-variables-considered-harmful/101953 "2006-08-08T21:33:32Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![darren\_kirby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ed8c4c/32.png) [@darren\_kirby](https://www.ruby-forum.com/u/darren_kirby)\
**Post date:** [August 8, 2006, 9:33pm UTC](https://www.ruby-forum.com/t/global-variables-considered-harmful/101953/1 "2006-08-08T21:33:32Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![darren\_kirby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ed8c4c/32.png) [@darren\_kirby](https://www.ruby-forum.com/u/darren_kirby)\
**Post date:** [August 8, 2006, 9:39pm UTC](https://www.ruby-forum.com/t/global-variables-considered-harmful/101953/2 "2006-08-08T21:39:33Z")

</div>

On 8/8/06, darren kirby [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Now I know you are not supposed to rely on globals if you can help it, so I am
> 
> - Dennis Ritchie and Ken Thompson, June 1972

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.

---

<div class="post-metadata">

**Author:** ![darren\_kirby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ed8c4c/32.png) [@darren\_kirby](https://www.ruby-forum.com/u/darren_kirby)\
**Post date:** [August 8, 2006, 9:42pm UTC](https://www.ruby-forum.com/t/global-variables-considered-harmful/101953/3 "2006-08-08T21:42:33Z")

</div>

On Aug 8, 2006, at 2:37 PM, Francis C. 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.

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

James Edward G. II

---

<div class="post-metadata">

**Author:** ![darren\_kirby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ed8c4c/32.png) [@darren\_kirby](https://www.ruby-forum.com/u/darren_kirby)\
**Post date:** [August 8, 2006, 9:51pm UTC](https://www.ruby-forum.com/t/global-variables-considered-harmful/101953/4 "2006-08-08T21:51:34Z")

</div>

darren kirby wrote:

> Now I know you are not supposed to rely on globals if you can help it, so I am
> 
> - Dennis Ritchie and Ken Thompson, June 1972  
> 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  
[Inversion of Control Containers and the Dependency Injection pattern](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

---

<div class="post-metadata">

**Author:** ![darren\_kirby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ed8c4c/32.png) [@darren\_kirby](https://www.ruby-forum.com/u/darren_kirby)\
**Post date:** [August 8, 2006, 10:03pm UTC](https://www.ruby-forum.com/t/global-variables-considered-harmful/101953/5 "2006-08-08T22:03:35Z")

</div>

quoth the Francis C.:

> On 8/8/06, darren kirby [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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  
you saying that optparse is preferable here?

In any event, using a plain or open struct seems like a better way to go  
than  
using a class.

Thanks guys,  
-d

---

<div class="post-metadata">

**Author:** ![darren\_kirby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ed8c4c/32.png) [@darren\_kirby](https://www.ruby-forum.com/u/darren_kirby)\
**Post date:** [August 8, 2006, 10:15pm UTC](https://www.ruby-forum.com/t/global-variables-considered-harmful/101953/6 "2006-08-08T22:15:36Z")

</div>

quoth the removed\_email\_address@domain.invalid:

> Well, this is quite a “can of worms” topic, now isn’t it?

He, well, I certainly didn’t intend for it, I am simply a self-taught  
programmer who lacking a formal education tries to muddle through and  
pick up  
some sage advice from here and there when possible…

> encapsulate and the script doesn’t know where they came from or how  
> 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  
concepts  
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!

> Ken

-d

---

<div class="post-metadata">

**Author:** ![darren\_kirby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ed8c4c/32.png) [@darren\_kirby](https://www.ruby-forum.com/u/darren_kirby)\
**Post date:** [August 8, 2006, 10:36pm UTC](https://www.ruby-forum.com/t/global-variables-considered-harmful/101953/7 "2006-08-08T22:36:38Z")

</div>

On Aug 8, 2006, at 2:50 PM, removed\_email\_address@domain.invalid wrote:

> 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:

> > require “singleton”  
> > =\> true
> 
> > class Config  
> > include Singleton  
> > end  
> > =\> Config
> 
> > p Config.instance.object\_id  
> > 1651794  
> > =\> nil
> 
> > # and later, in an unrelated piece of code…

?\> p Config.instance.object\_id  
1651794  
=\> nil

James Edward G. II

---

<div class="post-metadata">

**Author:** ![darren\_kirby](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/ed8c4c/32.png) [@darren\_kirby](https://www.ruby-forum.com/u/darren_kirby)\
**Post date:** [August 8, 2006, 11:12pm UTC](https://www.ruby-forum.com/t/global-variables-considered-harmful/101953/8 "2006-08-08T23:12:41Z")

</div>

On Wed, 9 Aug 2006, darren kirby wrote:

> 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 C. Phone : (64)(3) 358 6639  
Tait Electronics Fax : (64)(3) 359 4632  
PO Box 1645 Christchurch Email : removed\_email\_address@domain.invalid  
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.
