views:

656

answers:

16

I have a variable that I'm using like a constant (it will never change). I can't declare it as a constant because the value gets added at runtime.

Would you capitalize the variable name to help yourself understand that data's meaning?

Or would you not because this defies convention and make things more confusing?

The larger question:
Do you follow conventions even if the scenario isn't typical of the convention, but close enough that it might help you, personally, to understand things?

A: 

is it possible to mark it as readonly? Then conventions are not as important.

Rob
+10  A: 

If it will aid you (and everybody else) in understanding your code six months down the line, do it. If it won't, don't. It's really that simple.

Personally, I would capitalise it. This is the convention in Java, where constants are always allocated at runtime due to its object-oriented nature. I'd be much more comfortable knowing that if I accidentally assigned to it, I'd definitely notice the next time I scanned through that chunk of code.

Samir Talwar
In Java he could declare it final and be done with it.
quant_dev
+1  A: 

I would name it as a variable, I prefer to keep my naming very consistent. As Rob already suggested, what about readonly (available in C# at least). Or a property with no setter.

Lillemanden
+9  A: 

I don't consider my personals need to be paramount here -- if I've written the code, I'm already better placed to retrace it in the future if and when that's needed, than anybody else; so it's the "anybody else" I put first and foremost -- a present or future teammate that will need to understand the code (ideally) as thoroughly as I do.

Besides, with mandatory code reviews as a prereq to committing ANYthing to the codebase (an excellent practice, and the unfailing rule at my present employer), I'm likely to be called up on it should I ever let my attention slip (it does happen -- which is why I LOVE those mandatory code reviews, as applied to myself as well as everybody else!-).

A "variable set only once at startup" is a special-enough case that may be worth adding to your team's guidelines -- treating it as "closer to a constant than a variable" may make a lot of sense, but that only helps if the same rule/guideline is used consistently across the codebase. If the rule is not there I would check if there's consensus about adding it; otherwise, I would NOT break the guidelines for the sake of my personal tastes... that's the root of "egoless programming" and "team ownership of the codebase", two principles I serve with burning ardor.

BTW, were I on a single-person team in terms of coding guidelines (it happens, though it's not an optimal situation;), I think I'd have no trouble gaining unanimous consensus by myself that treating "set-once at startup" variables as constants in terms of naming conventions!-). But with a larger team, that's more work, and it could go either way.

Alex Martelli
If I could vote this one up more times than once, I'd do so. This is exactly the right answer. Good naming is part of consistent communication, which means the right answer isn't what any of us feel, but about the team and organization.
CPerkins
@CPerkins, thanks! We couldn't agree more.
Alex Martelli
A: 

Do you follow conventions even if the scenario isn't typical of the convention, but close enough that it might help you, personally, to understand things?

Following a convention when the scenario is atypical might confuse or slow down others (or even you, after a while.) I would avoid giving a variable the guise of something that it isn't.

Also, the fact that you have this atypical scenario could be an indication that perhaps some other, more typical paradigm could be followed. Though, I don't have any immediate suggestions for a alternative.

Ates Goral
A: 

I would make it capitalized (since it's more constant than variable from a design perspective) and add a comment around it stating its uniqueness to the application.

jinxx0r
A: 

FWIW my own convention is to use all caps for #defines and for enums. For const variables I either use no particular convention, or when I do it's to prefix the name with a 'k' (for 'konstant' - not 'c' which is already over used for things like 'count' or 'char').

I'm finding that I like the 'k' convention and will probably use it more often, and may even use it for enums, reserving the screaming, all-caps identifiers for the dreaded preprocessor macros.

Michael Burr
A: 

First of all, follow your project's coding standards. You should be coding for other people reading the code, not yourself. Your personal preferences should not take precedence over project-wide rules and conventions, etc.

In the absence of a project coding standard you should follow "best practice" for the language you are dealing with.

In Java, best practice is that you should declare a pseudo-constant with a camel case identifier. That's what the Sun Java coding standard says, and that is what the vast majority of professional Java developers use.

In C and C++ the (classical) convention is that all-caps is used for constants defined as preprocessor symbols. So since this is not a preprocessor symbol, you should use whatever your coding standard says is appropriate for a variable.

The fact that the pseudo-constant is not supposed to change won't stop someone from modifying the code so that it actually changes, accidentally or deliberately. If you use / abuse a coding convention that makes the identifier look like a real constaint, you will be part of the problem:

  1. Someone trying to read / debug your code will first assume the identifier is a real constant and not investigate the possibility thatit is not.
  2. Then when they do lookat the declaration, there will be alot of shouting and threats of defenestration.

Actually, a better way to deal with a pseudo-constant is to encapsulate it. In Java, you would declare it as private member and provide a getter and setter. The setter should do something to prevent the pseudo-constant from being changed after it has been set the first time. Any decent Java JIT compiler will inline a simple getter, so this should not affect runtime performance.

Stephen C
A: 

Conventions are just that, conventions. They are there to help the code understandable. They usually do if they are not too badly chosen and if they are applied consistently. The last point is probably the most important thing about them: they should be applied consistently.

One thing which prevent some conventions to make code more readable even when they are applied consistently -- at least for new comers and people switching between code base -- is when they are conflicting with other conventions. In C and C++, I'm aware of two common conventions about the use of names in ALL_CAPS:

  • reserve them for the preprocessor; that one has my preference as the preprocessor identifier are special: they don't obey usual scoping rule and preventing clashes with them is important

  • use them for constant (macro and enumerators).

Two problems comes in addition to the unfamiliarity if you use them for logically constant things which are in fact variable:

  • they aren't usable in places (like array size) where the language expect constant expression

  • my experience teach me that maintenance will tend to make them even less constant that they are now.

AProgrammer
A: 

Create a wrapper class with a single private static field. Create an initField(..) and a getField(..) static method. initField throws/asserts/otherwise errors if the static field is not null. (For primitives, you may have to use a primitive and a boolean to track initialization.)

In java, I prefer to pass these types of variables in as system properties. A static class can then do something like:

public final int MY_INT = Integer.getInteger("a.property.name");

You could also use a property file (see java.util.Properties) instead of using -D to specify it. Then you get:

public class Foo {

public static final int MY_INT;

static {
Properties p = new Properties();
try{
p.load( new FileInputStream("app.props"):
} catch(IOException e) {
//SWALLOW or RETHROW AS ERROR
}
MY_INT=Integer.parseInt( p.getProperty("my.int","17") ); //17 is default if you swallo IOException
}
...
}
KitsuneYMG
+1  A: 

Encapsulate it.

#include <iostream>

class ParamFoo
{
    public:
        static void initializeAtStartup(double x);
        static double getFoo();
    private:
        static double foo_;
};

double ParamFoo::foo_;

void ParamFoo::initializeAtStartup(double x)
{
    foo_ = x;
}

double ParamFoo::getFoo()
{
    return foo_;
}

int main(void)
{
    ParamFoo::initializeAtStartup(0.4);
    std::cout << ParamFoo::getFoo() << std::endl;
}

This should make it pretty clear that you shouldn't be setting this value anywhere else but at the startup of the application. If you want added protection, you can add some private guard boolean variable to throw an exception if initializeAtStartup is called more than once.

quant_dev
+1  A: 

My immediate impression is that something that you "set at runtime, then never change" is a constant, only so far as the business rules are constant. Also, you should be using mutators/accessors, since using ALL CAPS can hardly guarantee "constness".

public class BadClass
{ 
    public static final double PI = 3.1;     
      // PI is very constant.  Not according to the business roles modeled by my 
      // application, but by nature.  I don't have a problem making this publicly
      // accessible--except that [Math] already does, with much better precision)

    public static /*final*/ int FOO = null;
      // FOO is constant only by convention.  I cannot even enforce its "constness".
      // Making it public means that my enemies (overtime, for example) can change 
      // the value (late night programming), without telling me.
}

Instead,

public class BetterClass
{
    public static final double PI = 3.1;
    private /*final*/ Integer foo = null; 

    public int getFoo() {
        return this.foo.intValue();
    }
    public void setFoo(int value) {
        // The business rules say that foo can be set only once.
        // If the business rules change, we can remove this condition 
        // without breaking old code.
        if ( null == this.foo ) {
           this.foo = value;
        } else {
           throw new IllegalStateException("Foo can be set only once.");
        }
    }
}

If you always use the mutator to set the value, even within [BetterClass] itself, you know that the foo's "constness" will not be violated. Of course, if someone is going to set the value of foo directly (I need to quit working before 2:00 am!), there are still no guarantees. But something like that should be pointed out at code review.

So my recommendation is to treat foo as a normal member variable--there doesn't need to be a special naming convention for something that is almost const.

However, use mutators/accessors, even on private variables. These are typically very fast, and you can enforce business rules inside of them. This should be you convention.

(If you are writing code for embedded medical devices, pretend that you never saw this posting).

Paul Hanbury
A: 

Giving wrong information is generally not best practise.

Implicitly claiming something is a constant, when it is merely currently not changed, is giving out wrong information.

soru
A: 

one question would be: what kind of variable?

in the case of static variables, that don't change after what i'd call "boot-time" for the lack of a better term, i use ALL_CAPS ... same thing for global variables (if the language supports them at all) ...

communicating semantics is actually the point of naming conventions, and seeing an ALL_CAPS clearly states, that a) i will not write to it b) i can cache it (to a local variable for example, or in AS3 even an instance variable makes sense, since static access is very slow) ...

whether it's a "real constant" or not does not really matter ... that's more of an implementation detail, that should be hidden away (reliably! information hiding is good, and important, but it is crucial, that the information that is shared, can be trusted!) ... it can really be exchanged ... for example, i often start building apps vs. some hardcoded config, containing some static constants ... later, i decide that i don't want this to be hardcoded, but rather coming from some config file, so i load it, and during boot process, i init all the pseudo-constants ... the actuall app still treats them as constants, because after booting, that is what these values are ... this seems perfectly valid to me ...

at instance level, i am not 100% sure, if i ever ran into a case, where i could be very certain, that some field would never change ... usually, this makes the class unflexible ...

other than that, you can usually declare readonly properties, to have compile time errors, which is also a good thing to have ...

greetz

back2dos

back2dos
A: 

I'm not sure if this is legal in your language of choice, but in C++, this would work for your purpose:

#include <iostream>

int main()
{
    int i = 0;
    std::cin >> i;

    const int CONST = i; 
    std::cout << CONST; //displays i

    system("PAUSE"); 
    return 0;
}

I'm not sure if this is a moral thing to do, but this does solve your problem (unless you really need your memory).

Hooked
A: 

Just like anything else - scope and context are required to know in what way something is constant. So - there's no way to to satisfy everyone.

Follow the style used in your language of choice - 80% of the time, that will be clear enough. The alternative is a highly over-though nameing system that sacrifices productivity for ideal technical correctness (which few people will even really appreaciate if you can ever achieve it.)

sylvanaar