Using a constant by dereferencing a string
Sandbo
Hi,
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
>>101
string a = "test"
variable b = $a
print b
>>101
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.
January 20, 2019 at 06:54 pm - Permalink
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 k1 = 1
Constant k2 = 2
Function Test(str)
String str
Variable value
strswitch(str)
case "Zero":
value = k0
break
case "One":
value = k1
break
case "Two":
value = k2
break
default:
value = NaN
break
endswitch
return value
End
I would isolate this in a subroutine even if it were used only once to remove clutter from the calling routine.
January 20, 2019 at 10:13 pm - Permalink
In reply to >Somehow I forced it to work… 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.
January 21, 2019 at 07:29 am - Permalink
@Sandbo: Could you show your solution based on
Execute
?
I'm curious to know how that works.
January 21, 2019 at 08:23 am - Permalink
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:
Doing this without Execute would be difficult.
January 21, 2019 at 09:47 am - Permalink
In reply to @Sandbo: Could you show your… by thomas_braun
*This is not the recommended way to use constant per hrodstein, but it's actually quite neat:
//(Now assuming a popup control sets pa.popStr = "Digitizer1", inside a function)
string DIGname = pa.popStr
//Update DIGid
NVAR 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.
January 21, 2019 at 10:11 am - Permalink
@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.
January 21, 2019 at 12:10 pm - Permalink