Using a constant by dereferencing a string


I am trying to make use of some defined constants by their name.
This works in console, given I have a constant called test = 101

constant test = 101

string a = "test"
variable b = $a
print b

However, this doesn't work in the procedure, it simply say $ cannot be used this way.
Is there a work around for this?

Somehow I forced it to work by using Execute command in a function. Now sure if this is a good way though.

Somehow I forced it to work by using Execute command in a function. Not sure if this is a good way though.

Almost certainly not.

It seems like you are trying to use a constant for a purpose for which it is not fit, but I would need a more complete example to understand what your goal is.

If you are trying to choose a value based on the contents of a string, try something like this:

Constant k0 = 0
Constant k1 = 1
Constant k2 = 2

Function Test(str)
    String str
    Variable value
        case "Zero":
            value = k0
        case "One":
            value = k1
        case "Two":
            value = k2
            value = NaN
    return value   

I would isolate this in a subroutine even if it were used only once to remove clutter from the calling routine.

In reply to by hrodstein

Yes, I agree this can be better done with a stringswitch case, but it will add overhead for future expansion.

The case I am considering here is for adding new instrument to a system.
By using constant, I can easily assign a string with a constant, say 

constant Digitizer1 = 101

where 101 is of a specific format which tells typeOfInstru/BrandOfInstr/ChannelOfInstru.
Then in the future if a new machine is added I could add a new constant. This number (101) will be used as a input for another routine to tell which machine to apply a setting to.

Thanks for the idea, I will consider using a subroutine instead.
But in the case using Execute, is there any obvious problem you can spot now? As it is really tempting that I could have saved the overhead by using the constant.

but it will add overhead for future expansion

Overhead matters only if you are calling a function in a tight loop. If you need to convert from a string to a number, you can convert outside of the loop and the overhead will be insignificant.

Execute is probably slower than a strswitch. It is also kludgy. The command can not be debugged.

I can think of only a few, limited cases where Execute is advisable.

1. For window recreation macros created automatically by Igor.

2. Execute/P is useful when you need to defer an action until after procedure execute finished.

3. Execute is useful when you need to compose a command with a variable number of parameters, something that Igor does not handle elegantly. For example:

Function Demo(listOfWaves)
	String listOfWaves		// Comma-separated list of 1 to 10 waves
	String cmd
	sprintf cmd, "Display %s", listOfWaves
	Execute cmd

Doing this without Execute would be difficult.


In reply to by thomas_braun

*This is not the recommended way to use constant per hrodstein, but it's actually quite neat:

constant Digitizer1 = 123

//(Now assuming a popup control sets pa.popStr = "Digitizer1", inside a function)
string DIGname = pa.popStr

//Update DIGid
Execute "DIGid = $DIGname"

//Then the variable DIGid now is assigned with 123

The great thing with this is now I just need a separated procedure files which contains a bunch of constants, though in fact having a subroutine doesn't add that much work.

@Sandbo: Thanks. Now I see.

This will not be fast and also I would try to avoid Execute as much as possible. You only use it to map a string to a number and the solution from Howard is definitly the right choice for that.

PS: Depending on the runtime complexity of strswitch (linear or logarithmic) there might exist faster solutions for more than 1000 string->digit pairs but that should be of no real concern now.