Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Globals or objects?

0 views
Skip to first unread message

MartinR...@gmail.com

unread,
Feb 21, 2008, 7:16:04 AM2/21/08
to
I had a global variable holding a count. One source Google found
suggested that I wouldn't need the global if I used an object. So I
created a Singleton class that now holds the former global as an
instance attribute. Bye, bye, global.

But later I thought about it. I cannot see a single advantage to the
object approach. Am I missing something? Or was the original global a
better, cleaner solution to the "I need a value I can read/write from
several places" problem?

Steve Holden

unread,
Feb 21, 2008, 7:40:40 AM2/21/08
to pytho...@python.org

Look up "coupling" and "cohesion" in Wikipedia or similar, and you will
find out that global variables are bad because they introduce tight
coupling between different pieces of functionality in your code.

If a function uses a global variable then you have to initialize the
same global variable in another program that uses it: yet another piece
of setup you will forget to do.

Having said that, where are you storing the reference to the singleton
instance? It wouldn't be a global, would it?

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/

Hrvoje Niksic

unread,
Feb 21, 2008, 8:01:52 AM2/21/08
to
Steve Holden <st...@holdenweb.com> writes:

> If a function uses a global variable then you have to initialize the
> same global variable in another program that uses it: yet another
> piece of setup you will forget to do.

If the global variable belongs to the module, then it is up to the
module to initialize it. A different program program will simply
import the same module and automatically get the same variable,
properly initialized.

One reason why a singleton's attribute may be better than a global
variable is that it's easier to later add a callback when the value is
changed without breaking the interface. A module cannot react to
module.somevar = value; on the other hand, a singleton can implement
__setattr__ that reacts to module.singleton.attr = value.

Aahz

unread,
Feb 21, 2008, 8:25:58 AM2/21/08
to
In article <72b59db8-ec9c-480a...@41g2000hsc.googlegroups.com>,

The advantage of the global singleton is that it is a container;
therefore, its contents are mutable and you don't need to keep using the
``global`` statement.
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/

"All problems in computer science can be solved by another level of
indirection." --Butler Lampson

tin...@isbd.co.uk

unread,
Feb 21, 2008, 8:41:22 AM2/21/08
to
Steve Holden <st...@holdenweb.com> wrote:
> MartinR...@gmail.com wrote:
> > I had a global variable holding a count. One source Google found
> > suggested that I wouldn't need the global if I used an object. So I
> > created a Singleton class that now holds the former global as an
> > instance attribute. Bye, bye, global.
> >
> > But later I thought about it. I cannot see a single advantage to the
> > object approach. Am I missing something? Or was the original global a
> > better, cleaner solution to the "I need a value I can read/write from
> > several places" problem?
>
> Look up "coupling" and "cohesion" in Wikipedia or similar, and you will
> find out that global variables are bad because they introduce tight
> coupling between different pieces of functionality in your code.
>
I think the OP was asking rather how the Object is any different from
the global if it's simply used as a wrapper for a single value.

In usage, philosophy or whatever it's effectively identical and
introduces all the same problems as a global does, it just gives it a
longer name.

Objects only become useful when the encapsulate more than on thing.

--
Chris Green

tin...@isbd.co.uk

unread,
Feb 21, 2008, 8:43:26 AM2/21/08
to
Aahz <aa...@pythoncraft.com> wrote:
> In article <72b59db8-ec9c-480a...@41g2000hsc.googlegroups.com>,
> <MartinR...@gmail.com> wrote:
> >
> >I had a global variable holding a count. One source Google found
> >suggested that I wouldn't need the global if I used an object. So I
> >created a Singleton class that now holds the former global as an
> >instance attribute. Bye, bye, global.
> >
> >But later I thought about it. I cannot see a single advantage to the
> >object approach. Am I missing something? Or was the original global a
> >better, cleaner solution to the "I need a value I can read/write from
> >several places" problem?
>
> The advantage of the global singleton is that it is a container;
> therefore, its contents are mutable and you don't need to keep using the
> ``global`` statement.

.... but you do keep having to use a longer reference to the value so
what have you won?

--
Chris Green

Duncan Booth

unread,
Feb 21, 2008, 8:47:35 AM2/21/08
to
MartinR...@gmail.com wrote:

A singleton is simply another form of global. The benefit of a singleton
is that it can be used to encapsulate several related values and methods
in a single globally accessible space. The easiest way in Python to
implement a singleton is just to use a module: all modules are
singletons and there is a defined mechanism (import) for accessing them.

It sounds as though you simply replaced a value stored in a singleton
object (global in a module) with a value stored in a singleton object
(attribute of your class) which is referenced from a singleton object
(your module).

The real benefit from using an object comes when you stop making it a
singleton. Create it at some high level in your code and pass it around
as a parameter, or hold a reference to it in some other object which is
passed around. When you do this you no longer have a global, and the
benefits you get include:

* for your counter example, you can have multiple counters counting
different things without having to duplicate counter code for each thing
you want to count.

* it becomes much easier to write tests for your code, because each test
can create its own context and be completely independant from the other
tests. e.g. you can test a generic counter without having to know you
are testing the foo counter or the bar counter, and you can test
something which counts foos without having to worry that other tests may
already have counted some foos.

There is another lesser (and Python specific) benefit to storing a value
as an attribute of a class rather than a global in a module: if you
later want to intercept assignments to the attribute you can turn it
into a property, but doing the same thing on a module is much harder.

James Newton

unread,
Feb 21, 2008, 9:47:17 AM2/21/08
to pytho...@python.org
Duncan Booth wrote:
> The easiest way in Python to implement a singleton is just to
> use a module: all modules are singletons and there is a
> defined mechanism (import) for accessing them.

Hi Duncan,

I'm intrigued by this idea.

Could you give a bare-bones demonstration of it that the relative newbie
that I am can understand?

Thanks in advance,

James

Mel

unread,
Feb 21, 2008, 10:11:52 AM2/21/08
to
James Newton wrote:
> Duncan Booth wrote:
>> The easiest way in Python to implement a singleton is just to
>> use a module: all modules are singletons and there is a
>> defined mechanism (import) for accessing them.
[ ... ]

> Could you give a bare-bones demonstration of it that the relative newbie
> that I am can understand?

I had a club-membership application that ran for several years.
Default pathnames, etc. for the particular year came from a module
called thisyear.py:
#=========================


'''Values used to access this years trakkers files.
$Id: thisyear.py,v 1.2 2006/08/26 16:30:23 mwilson Exp $
'''

memberpath = '2006-7/20062007.txt' # path to this years membership CSV
dirname = '2006-7' # directory name for this year


#=========================
Programs that needed to use the comma-separated-value membership base
would import thisyear, and pass thisyear.memberpath when creating the
CSV reader object. Etc.

Mel.

Aahz

unread,
Feb 21, 2008, 10:42:27 AM2/21/08
to
In article <47bd7ffe$0$514$bed6...@news.gradwell.net>,

Clarity, simplicity, robustness

James Newton

unread,
Feb 21, 2008, 11:27:06 AM2/21/08
to pytho...@python.org
Mel wrote:
>> James Newton wrote:
>> Could you give a bare-bones demonstration of [implementing a
singleton
>> by using a module]?

>
> I had a club-membership application that ran for several years.
> Default pathnames, etc. for the particular year came from a module
> called thisyear.py:
> #=========================
> '''Values used to access this years trakkers files.
> $Id: thisyear.py,v 1.2 2006/08/26 16:30:23 mwilson Exp $
> '''
>
> memberpath = '2006-7/20062007.txt' # path to this years membership CSV
> dirname = '2006-7' # directory name for this year
> #=========================
> Programs that needed to use the comma-separated-value membership base
> would import thisyear, and pass thisyear.memberpath when creating the
> CSV reader object. Etc.

Hi Mel,

So you were using thisyear.py as a preferences file: making it a module
was a shortcut for reading in the file and parsing its contents. I like
it.

Would there be any circumstances where the singleton module would
include functions and objects? In particular, would this system work if
the application needed to change a value (such as a counter)?

Suppose your application wanted to save the changed value, so that the
next session started using the new value. Could you simply write out a
new copy of the thisyear.py file? Or would this lead to version issues?
Would a previously-imported version of the module be stored in a
different place in RAM than a module that was imported after the change
was made?

Perhaps my real question is about how to visualize a module: what makes
an imported module different from an instance?

Thanks for your insights,

James

tin...@isbd.co.uk

unread,
Feb 21, 2008, 11:37:56 AM2/21/08
to
Aahz <aa...@pythoncraft.com> wrote:
> In article <47bd7ffe$0$514$bed6...@news.gradwell.net>,
> <tin...@isbd.co.uk> wrote:
> >Aahz <aa...@pythoncraft.com> wrote:
> >> In article <72b59db8-ec9c-480a...@41g2000hsc.googlegroups.com>,
> >> <MartinR...@gmail.com> wrote:
> >>>
> >>>I had a global variable holding a count. One source Google found
> >>>suggested that I wouldn't need the global if I used an object. So I
> >>>created a Singleton class that now holds the former global as an
> >>>instance attribute. Bye, bye, global.
> >>>
> >>>But later I thought about it. I cannot see a single advantage to the
> >>>object approach. Am I missing something? Or was the original global a
> >>>better, cleaner solution to the "I need a value I can read/write from
> >>>several places" problem?
> >>
> >> The advantage of the global singleton is that it is a container;
> >> therefore, its contents are mutable and you don't need to keep using the
> >> ``global`` statement.
> >
> >.... but you do keep having to use a longer reference to the value so
> >what have you won?
>
> Clarity, simplicity, robustness

Clarity - why is it clearer?

Simplicity - no, you've added an extra layer.

Robustness - how?

--
Chris Green

Duncan Booth

unread,
Feb 21, 2008, 11:40:42 AM2/21/08
to
"James Newton" <jne...@fuelindustries.com> wrote:

> Perhaps my real question is about how to visualize a module: what makes
> an imported module different from an instance?

On one level: nothing. An imported module is an instance of the module
type. Modules don't have to be associated with python code: you can create
additional module instances (by calling new.module) and populate them
however you wish.

What you get with a module is support for locating a specific module and
ensuring that you don't get duplicate copies of a named module.

What you lose is the ability to define methods: functions in a module don't
have a 'self' parameter. Also you can't override special methods for a
module, so it isn't quite equivalent to writing a class, but there are
similarities.

Regarding your question about saving the values: what you would usually do
would be to store the values in a separate configuration file and the
module would load them on startup and then rewrite the configuration file
when you call a save function. That way the module code itself isn't
changing. The 'singleton' config module would expose functions such as
'load', 'save', 'getXXX'.

James Newton

unread,
Feb 21, 2008, 12:03:25 PM2/21/08
to pytho...@python.org
Duncan Booth wrote:
> you can create additional module instances (by calling new.module)

Hi Duncan,

Could you provide a scenario where this would be useful (and the best
practice)?

> What you get with a module is support for locating a specific module
> and ensuring that you don't get duplicate copies of a named module.

So if I were to execute the following pseudo-code, the second 'import'
would simply point at the module (instance) imported the first time:

import mymodule
changeContentsOf("mymodule.py") #on the hard disk
import mymodule

The values, functions and classes available in mymodule would only
change if I were to restart the application.

> Regarding your question about saving the values: what you would
> usually do would be to store the values in a separate configuration
> file and the module would load them on startup and then rewrite the

> configuration file when you call a save function...

That's what I would normally do, too.

Thanks for your help,

James

Steven D'Aprano

unread,
Feb 21, 2008, 5:32:37 PM2/21/08
to
On Thu, 21 Feb 2008 16:37:56 +0000, tinnews wrote:

> Aahz <aa...@pythoncraft.com> wrote:
>> In article <47bd7ffe$0$514$bed6...@news.gradwell.net>,
>> <tin...@isbd.co.uk> wrote:
>> >Aahz <aa...@pythoncraft.com> wrote:
>> >> In article
>> >> <72b59db8-ec9c-480a...@41g2000hsc.googlegroups.com>,
>> >> <MartinR...@gmail.com> wrote:
>> >>>
>> >>>I had a global variable holding a count. One source Google found
>> >>>suggested that I wouldn't need the global if I used an object. So I
>> >>>created a Singleton class that now holds the former global as an
>> >>>instance attribute. Bye, bye, global.
>> >>>
>> >>>But later I thought about it. I cannot see a single advantage to the
>> >>>object approach. Am I missing something? Or was the original global
>> >>>a better, cleaner solution to the "I need a value I can read/write
>> >>>from several places" problem?
>> >>
>> >> The advantage of the global singleton is that it is a container;
>> >> therefore, its contents are mutable and you don't need to keep using
>> >> the ``global`` statement.
>> >
>> >.... but you do keep having to use a longer reference to the value so
>> >what have you won?
>>
>> Clarity, simplicity, robustness
>
> Clarity - why is it clearer?

Consider two function calls:


x = ham(arg, counter)
y = spam(arg)

Both do exactly the same thing: ham() takes an explicit "counter"
argument, while spam() uses a global variable. Which one makes it clear
that it uses a counter, and which does not?


> Simplicity - no, you've added an extra layer.

Consider trying to run ham() and spam() twice, independently:

x1 = ham(arg, counter)
x2 = ham(arg, another_counter)

y1 = spam(arg)
saved_counter = counter # save the global variable
counter = 0 # reset it to zero
y2 = spam(arg)
another_counter = counter
counter = saved_counter


Which is simpler?



> Robustness - how?

If you avoid the use of globals, this code will work as expected:

x = ham(arg, counter)
assert counter.n = 5 # or whatever value ham() sets it to...
function()
another_function()
yet_another_function()

At the end of this block of function calls, you can be confident that
counter still has the same value.

Now consider using globals:

x = spam(arg)
assert counter = 5 # or whatever value spam() sets it to...
function()
another_function()
yet_another_function()

What value will counter have? The only way to tell is to carefully read
through function(), another_function() and yet_another_function() and see
whether or not they modify the global counter. Maybe they do, maybe they
don't, who can tell?


--
Steven

Duncan Booth

unread,
Feb 22, 2008, 5:42:36 AM2/22/08
to
"James Newton" <jne...@fuelindustries.com> wrote:

> Duncan Booth wrote:
>> you can create additional module instances (by calling new.module)
>
> Hi Duncan,
>
> Could you provide a scenario where this would be useful (and the best
> practice)?

Not really as such cases are few and far between. Try grepping the standard
library for a few examples where new.module is called.

>> What you get with a module is support for locating a specific module
>> and ensuring that you don't get duplicate copies of a named module.
>
> So if I were to execute the following pseudo-code, the second 'import'
> would simply point at the module (instance) imported the first time:
>
> import mymodule
> changeContentsOf("mymodule.py") #on the hard disk
> import mymodule
>
> The values, functions and classes available in mymodule would only
> change if I were to restart the application.

Yes, you could call 'reload(mymodule)' to force it to reload but otherwise
once it has been imported once any subsequent imports just return the
existing module.

MartinR...@gmail.com

unread,
Feb 22, 2008, 6:16:12 AM2/22/08
to
A fascinating, well-informed discussion. Thanks to all.

Holden's suggestion re coupling and cohesion was most informative. I
conclude that whether you use an object or a global (within a module,
not across modules) is an implementation detail that has no impact on
either cohesion or coupling.

D'Aprano's discussion is persuasive but only in the case where you do
not want multiple actors updating a single value. In my case multiple
actors have legitimate interest in updating the value. (Actors within
a single thread, fortunately.)

I conclude that intra-module globals are NOT always evil. They get a
bad rap because some of them are evil.

Anecdote proving nothing: My count got wrapped into an object. I found
additional uses for the object, so it stayed there. Finally, the count
and the object got designed out of the module. RIP.

tin...@isbd.co.uk

unread,
Feb 22, 2008, 7:01:20 AM2/22/08
to
Steven D'Aprano <st...@remove-this-cybersource.com.au> wrote:
> >> >.... but you do keep having to use a longer reference to the value so
> >> >what have you won?
> >>
> >> Clarity, simplicity, robustness
> >
> > Clarity - why is it clearer?
>
> Consider two function calls:
>
>
> x = ham(arg, counter)
> y = spam(arg)
>
> Both do exactly the same thing: ham() takes an explicit "counter"
> argument, while spam() uses a global variable. Which one makes it clear
> that it uses a counter, and which does not?
>
But you're not comparing what the OP posted. He was comparing a
global with an object with a single variable inside it. Either would
work with the y = spam(arg) example above.

I agree absolutely about the reason for not using globals but that
applies similarly to objects. The OP was comparing a global integer
variable with an object with a single integer variable in it.

>
> > Simplicity - no, you've added an extra layer.
>
> Consider trying to run ham() and spam() twice, independently:
>
> x1 = ham(arg, counter)
> x2 = ham(arg, another_counter)
>
> y1 = spam(arg)
> saved_counter = counter # save the global variable
> counter = 0 # reset it to zero
> y2 = spam(arg)
> another_counter = counter
> counter = saved_counter
>
> Which is simpler?

Again it's not what the OP was doing. I again agree absolutely that
in general globals are a 'bad thing' if you can avoid them but your
example doesn't really affect the original OP question.

>
>
>
> > Robustness - how?
>
> If you avoid the use of globals, this code will work as expected:
>
> x = ham(arg, counter)
> assert counter.n = 5 # or whatever value ham() sets it to...
> function()
> another_function()
> yet_another_function()
>
> At the end of this block of function calls, you can be confident that
> counter still has the same value.
>
> Now consider using globals:
>
> x = spam(arg)
> assert counter = 5 # or whatever value spam() sets it to...
> function()
> another_function()
> yet_another_function()
>
> What value will counter have? The only way to tell is to carefully read
> through function(), another_function() and yet_another_function() and see
> whether or not they modify the global counter. Maybe they do, maybe they
> don't, who can tell?
>

You're just telling me all the problems one can have with globals
which I know and agree with. But an object with a single variable in
it has exactly the same issues.

--
Chris Green

Steven D'Aprano

unread,
Feb 22, 2008, 9:01:47 AM2/22/08
to
On Fri, 22 Feb 2008 03:16:12 -0800, MartinRinehart wrote:

> D'Aprano's discussion is persuasive but only in the case where you do
> not want multiple actors updating a single value. In my case multiple
> actors have legitimate interest in updating the value. (Actors within a
> single thread, fortunately.)

You missed the point. It's not whether you only have *one* actor has to
update the value, or more than one. It's about having loose coupling
between the actors and the value.

Consider a thought experiment. Suppose somebody wrote a math library that
worked something like this:

# contents of maths.py
x = 0.0 # default value for global x

def sin():
taylor = x + x**2/2 + x**3/6
# Taylor's expansion of sine. (I think.)
return taylor


and so forth. To use this library, you would have to do this:

savex = maths.x
maths.x = 0.1
y = maths.sin() # multiple actors with a legitimate need
z = maths.cos() # to access a single global value
maths.x = savex


The functions are tightly coupled to x, and can't operate on anything
else other than x, so your program ends up being filled with wasteful
code storing the value of x, setting it to a value, then restoring it.

I think we will all agree that the above is a ridiculous way to write
code. But what you're doing differs from it only in degree, not kind: all
you're doing is replacing x with counter.

In your example, you say you have "multiple actors [with a] legitimate
interest in updating the [global] value." That's fine. But that *group*
of actors still behaves as a single entity. What happens when you have
two *groups*?

savecounter = counter
foo(actor1) # All these actors are in the same group:
foo(actor3) # "Odd" actors.
foo(actor5)
print counter
counter = savecounter
# But these are in a different group:
foo(actor2) # "Even" actors.
foo(actor4)

As soon as you have multiple groups, globals become a millstone around
your neck because of that tight coupling: your function foo() can't
operate on any value except counter. That makes testing very hard,
because your test functions can't provide their own counters.

Now, there are times where using globals is acceptable *in spite of* this
problem. For example, I will often use globals to write a piece of quick-
and-dirty through-away code. Or as a first draft: write a bit of code
using a global, get the basic algorithm working, then modify it to work
with a parameter instead. Or perhaps you've decided that you really
*want* that tight coupling. And you can't avoid globals altogether,
because there's always going to be a global scope.


--
Steven

Steven D'Aprano

unread,
Feb 22, 2008, 10:19:26 AM2/22/08
to
On Fri, 22 Feb 2008 12:01:20 +0000, tinnews wrote:

> Steven D'Aprano <st...@remove-this-cybersource.com.au> wrote:
>> >> >.... but you do keep having to use a longer reference to the value
>> >> >so what have you won?
>> >>
>> >> Clarity, simplicity, robustness
>> >
>> > Clarity - why is it clearer?
>>
>> Consider two function calls:
>>
>>
>> x = ham(arg, counter)
>> y = spam(arg)
>>
>> Both do exactly the same thing: ham() takes an explicit "counter"
>> argument, while spam() uses a global variable. Which one makes it clear
>> that it uses a counter, and which does not?
>>
> But you're not comparing what the OP posted. He was comparing a global
> with an object with a single variable inside it. Either would work with
> the y = spam(arg) example above.

What do you mean by "an object with a single variable inside it"? I don't
understand what that is supposed to mean, or why you think it is the same
as a global. Do you mean a Singleton?

If so, then the answer is simple: using a Singleton argument instead of a
global is better, because with a global you are stuck to always using the
global (at least until you can re-write the code), but with the Singleton
argument, you may be enlightened and *not* use a Singleton.

--
Steven

tin...@isbd.co.uk

unread,
Feb 22, 2008, 1:53:54 PM2/22/08
to
But if you stop using the Singleton the code no longer does the same
as it would with a global does it?

As I keep saying I agree wholeheartedly with the general idea that
globals are a bad thing. However wrapping up what is effectively a
global in a different construct doesn't seem to me to be any help at
all. What you need to do is take a long hard look at the global and
decide if there are better ways of doing it, not just simply wrap it
up in a class that really doesn't help at all.

--
Chris Green

Steven D'Aprano

unread,
Feb 22, 2008, 7:23:03 PM2/22/08
to
On Fri, 22 Feb 2008 18:53:54 +0000, tinnews wrote:

>> > But you're not comparing what the OP posted. He was comparing a
>> > global with an object with a single variable inside it. Either would
>> > work with the y = spam(arg) example above.
>>
>> What do you mean by "an object with a single variable inside it"? I
>> don't understand what that is supposed to mean, or why you think it is
>> the same as a global. Do you mean a Singleton?
>>
>> If so, then the answer is simple: using a Singleton argument instead of
>> a global is better, because with a global you are stuck to always using
>> the global (at least until you can re-write the code), but with the
>> Singleton argument, you may be enlightened and *not* use a Singleton.
>>
> But if you stop using the Singleton the code no longer does the same as
> it would with a global does it?

That's a *good* thing, not a problem. The whole idea is to get away from
the bad behaviour of globals, not find some other way to implement it.

--
Steven

tin...@isbd.co.uk

unread,
Feb 23, 2008, 4:32:24 AM2/23/08
to
Steven D'Aprano <st...@remove-this-cybersource.com.au> wrote:
That's *exactly* what I was saying in the bit you snipped! :-)

However it doesn't answer the OP's questionas to why he was advised to
replace a global with a class *without* changing the way it was used.

--
Chris Green

Steve Holden

unread,
Feb 23, 2008, 8:16:44 AM2/23/08
to pytho...@python.org
I think that advocation of a global singleton is not really solving the
problem. Not the problem I perceive, anyway. From your comments it's
difficult to see whether we share the same perceptions, so let me elucidate.

The issue I have with globals is primarily that use of a global
introduces a tight coupling between a function and its environment,
since any environment that uses the function has to provide the global.

It's true that a global singleton is a half-way step to a solution of
the problem because it portends the true solution, which also solves the
problem of multiple counts. That solution, of course, is to have the
"function" become a method of some counter object, which can then be
used to count many things.

In other words (untested, so ignore the many Holden types that this will
inevitably incur):

--------
bad.py:

counter = 0

def count(n):
global counter
counter += n
--------
justasbadifnotworse.py:

class bunch: pass;

counter = bunch()
bunch.count = 0

def count(n):
counter.count += n
--------
better.py:

class Counter:
def __init__(self):
self.count = 0

counter1 = Counter()
counter2 = Counter()

def count(n, counter):
counter.count += n
--------
best.py:

class Counter:
def __init__(self):
self.count = 0
def count(self, n):
self.count += n
--------

Now the names I have chosen are pejorative, but this is typically the
development you see in someone's programming style as they slowly (or
not slowly) start to understand the value of the object-oriented approach.

Unfortunately this sometimes goes too far, and people end up writing
"monster objects", with dozens of methods and lots of instance variables
used to communicate between them. With that style of programming the
instance variables introduce the same tight coupling between the methods
that globals do in a less object-oriented style, and the code becomes
just as difficult to understand. Only now there can be multiple
instances of the badly-written function!

Sometimes this is inevitable, but good programming style is about trying
to strike the right balance between contexts. It is truly possible to
write good and bad programs in any language you like, and rules like
"globals are bad" need to be taken in context just like any other rule.

After all, some things *have* to be global for our programs to make any
sense at all, unless you want to adopt a truly functional style that has
never appealed to me. I like my programs to have state.

Steven D'Aprano

unread,
Feb 23, 2008, 4:44:35 PM2/23/08
to
On Sat, 23 Feb 2008 08:16:44 -0500, Steve Holden wrote:

> Steven D'Aprano wrote:
>> On Fri, 22 Feb 2008 18:53:54 +0000, tinnews wrote:
>>
>>>>> But you're not comparing what the OP posted. He was comparing a
>>>>> global with an object with a single variable inside it. Either
>>>>> would work with the y = spam(arg) example above.
>>>> What do you mean by "an object with a single variable inside it"? I
>>>> don't understand what that is supposed to mean, or why you think it
>>>> is the same as a global. Do you mean a Singleton?
>>>>
>>>> If so, then the answer is simple: using a Singleton argument instead
>>>> of a global is better, because with a global you are stuck to always
>>>> using the global (at least until you can re-write the code), but with
>>>> the Singleton argument, you may be enlightened and *not* use a
>>>> Singleton.
>>>>
>>> But if you stop using the Singleton the code no longer does the same
>>> as it would with a global does it?
>>
>> That's a *good* thing, not a problem. The whole idea is to get away
>> from the bad behaviour of globals, not find some other way to implement
>> it.
>>
> I think that advocation of a global singleton is not really solving the
> problem. Not the problem I perceive, anyway. From your comments it's
> difficult to see whether we share the same perceptions, so let me
> elucidate.

Thanks for the details. I do agree with you. It wasn't me that suggested
that the OP create a global singleton, or that using such a beast was a
good plan. I hope that my response that [paraphrasing] a global singleton
was good because it lets the developer STOP using a global singleton can
be seen in context of tinnews badgering me again and again to explain why
using a global singleton is better than an old-style global variable.
That's not a position I would take.

[...]


> After all, some things *have* to be global for our programs to make any
> sense at all, unless you want to adopt a truly functional style that has
> never appealed to me. I like my programs to have state.

Some things are global, yes, but very few of them need to be "global
variables" in the sense we're discussing. Actually, in the sense of the
OP's example, I don't believe anything *needs* to be a global variable,
unless it's a deliberate design choice (e.g. a global flag controlling
some aspect of program behaviour, which I see as a legitimate if
restrictive choice).


--
Steven

0 new messages