How do I configure a ModelMap element after the "all" method has run?

software-model

(Martin d'Anjou) #1

ModelMap has an all method which I use to set a property in all elements. But I also want to override for some other elements. The following code shows how I thought I could do this for my custom plugin:

model {
    producers {
        scifi {
            all {
                enable = false
            }
            test {
                enable = true
            }
        }
    }
}

However I am puzzled, as when I print the enable value for test, it is false. Tracing with println statements confirms that the all closure runs after the test closure.

Is there a way to configure test (run its closure) after the all closure has run instead (to get test.enable == true)?


(Daniel Lacasse) #2

Thanks Martin for the precise question. You can’t assume any order for the same configuration scope. Both configurations you have now runs at the Mutate configuration level. I see two ways to fix this problems.

One way would be to use the afterEach and filter for your the getName() that equals to test.

Another way is to use Object that enables you to have an not set state. In your scenario, you could use Boolean and assume null as not set. Instead of using all, you can use afterEach and change enable for any object that didn’t set it.

Don’t hesitate to ask more question,

Daniel


(Martin d'Anjou) #3

I agree with the Mutate order of execution being unspecified. I discovered this whilst transforming my plugin (pushing a ModelMap down one level of hierarchy - it used to be one level higher), and it caught me by surprise.

For the record, initially I had the following case where the all executed after the test1, which I now realize was wrong to rely on!

model { 
    shallow { 
        all { 
            enable = false 
        } 
        test1 { 
            enable = true 
        } 
    } 
}

Using afterEach does work, but it does not look as elegant. Thanks Daniel.