Explicity refer to global variable?

Is there a way to refer to a global/module level variable from a scope where it is shadowed? I've seen things like Swift.foo before to refer to foo in the standard library. But in this example below, the code is inside a Swift package. Neither Swift nor my package name works in place of the ??? below.

private var logDebug: Bool = false

public class Foo {
    public static var logDebug: Bool {
        get { ???.logDebug }  // trying to refer to the top level `logDebug` above
        set { ???.logDebug = newValue }
    }
}

Use the module name in place of ???. If you are using SwiftPM, the module name is the same as the target name*.

*unless you named the target something that would be invalid as a module name, in which case SwiftPM will have sanitized it for you. e.g. My ModuleMy_Module

I tried that. The package and target both have the same name. I get the error: "Type 'MyModule' has no member 'logDebug'".

It may work if logDebug isn't private. I'd guess that, in marking it private, you've made it invisible to the module namespace.

I tested this two ways:

  • I created a test framework in Xcode (using Xcode 11.4 btw), added a new file named Foo.swift with the code above, and then replaced ??? with the framework name. It built just fine.

  • I create a new package in Xcode, replaced MyLibrary.swift with the code above, replaced ??? with MyLibrary, and it also built just fine.

I’m not sure what’s going on in your specific case, but I’m not seeing it. Can you run through the tests above to see if you can replicate my results?

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

If you read the error carefully you see you're actually trying to refer to a type not module named MyModule. This happens because types currently take precedence in name lookup over modules, and you apparently reuse the same name for both in this case.

It's a known shortcoming in Swift today. AFAICT your only options are to rename the type or module (a common pattern for the latter being MyModuleKit), or to rename the variable so that it needs no qualification.

3 Likes

I tried the simple tests as you suggested and it led me to the problem. :man_facepalming: Sorry to waste people's time. When you create a Swift Package in Xcode it creates a struct with the same name as your module. I had never deleted that file, and didn't notice it in the sea of almost 100 other files. I deleted that struct and everything works as expected.