This message was deleted.
# questions
s
This message was deleted.
s
We've had similar things happen and I'm fairly certain it's because of Groovy 3 now enforces visibility whereas before it would allow you to circumvent it. In actuality the current behaviour is more correct, because the closure you have defined there, is executed lazily by the
bindNode
method of the
StreamingMarkupBuilder
class, and that method/class should not be able to see private method. So it effectively calls
owner.toIF( ... )
which you would expect to be an access violation. You can actually evaluate the example you show there before calling the binder, and that value will be in the scope of the builder and so it should be able to see it. Although there may be instances elsewhere in your codebase that you can not do this, in which case the best option is to make the method public (as you have done) as it reflects the usage clearly. Something like the following would work for the example...
Copy code
class TestMarkup{
    private String toTF(value) {
        return value ? "true" : "false"
    }
    
    Map status = [someBoolean: true]

    
    def getBuilder() {
        // Executed in the scope of `TestMarkup` can see private scoped values.
        final String indicatorVal = toTF(status?.someBoolean || status?.someBoolean)

        return new StreamingMarkupBuilder().bindNode {
            // Executed later by `StreamingMarkupBuilder` shouldn't be able to see values outside the scope of the `getBuilder` inner stanza
            Indicator(indicatorVal)
        }
    }
}

new TestMarkup().getBuilder()
👍 1
g
Interesting, this must have been a leak from Groovy 4 to 3 because in the Groovy 4 release notes:
Copy code
We are currently attempting to improve how Groovy code accesses private fields in certain scenarios where such access is expected but problematic, e.g. within closure definitions where subclasses or inner classes are involved (GROOVY-5438). You may notice breakages in Groovy 4 code in such scenarios until this issue is progressed. As a workaround in the meantime, you may be able to use local variable outside a closure to reference the relevant fields and then reference those local variables in the closure.
However what is weird is in a fresh app the call to the private method will work, In a simple example like the one posted but in the app I'm working on the conditions are right for it to fail... In any case thanks for the insight.
👍 1
s
It is V. strange that it works for you on fresh app...
g
Yeah, I was driving myself crazy debugging it yesterday because it would work in a fresh app, if I printed to the console, but then "fail" I called it while debugging in Intellij's Expression Evaluator.