Attributes and constant values
So there is an interesting problem that crops up when you try to use a constant for an attribute value. I use the term "problem" here in a loose sense, it's actually just a behavior to be aware of since it's a bit of an edge case. The "problem" boils down to what the context is for resolving a constant in an attribute list. Given the following code:
Attributes( SomeName = kTest ) Class Class1
Const kTest = "Hello world"
End Class
One might think that this code is perfectly legal, but one would be wrong in that case. When resolving a constant within an attribute list, the compiler must use the containing scope. In this case, the containing scope is the global namespace (because Class1 is being declared at the root level). The compiler cannot use Class1 to resolve the constant symbol because it is unknown what the attribute will be applied to until *after* the attribute has been compiled. It's sort of a sticky situation because the code looks reasonable, however, it's the correct behavior. Think about it this way: when you declare a method, you don't expect any of the method body's declaration to be available to the method declaration itself. So you cannot declare a local constant that you are able to use as a parameter optional value. This is really not much different.
When working with attributes, if you plan to use a constant as the value you should be aware of this and understand the limitations of the feature. You must assume that attributes are compiled with the containing context and then applied to the item they modify. So in the above code example, you could use Attributes( SomeName = Class1.kTest ) because kTest is public, and you're using a fully-qualified name to reach the constant. Another example would be:
Module Module1
Const kTest = "Hello world"
Attributes( SomeName = kTest ) Class Class1
End Class
End Module
That will compile fine because kTest is defined within the module's scope.
Just a little tidbit to remember, that's all!
Leave a comment