xTend: How to stop a variable from printing in output?
Asked Answered
S

3

6

Lets say you have the following code in xTend:

class StackOverflowGenerator {
    def generate()'''
    «var counter = 0»
    «FOR i : 0 ..<10»
    Line Numnber: «i»
    «counter = counter + 1»
    «ENDFOR»
'''

}

This will generate output in the format:

    Line Numnber: 0
    1
    Line Numnber: 1
    2
    Line Numnber: 2
    3
    Line Numnber: 3
    ...

How do I get xTend to not print the line with just the counter and only print the Line Number line such that the output looks like:

Line Numnber: 0
Line Numnber: 1
Line Numnber: 2
Line Numnber: 3
...
Sisyphus answered 23/8, 2013 at 17:58 Comment(1)
What is the purpose of 'counter' variable? Why not just use i?Cassirer
S
3

In your example there is no use for counter. So it is hard to guess what your real usecase is. In most cases some calculation based on i is enought, eliminating counter completely. Orionll's answer is pointing in that direction.

If however counter is something which cannot be computed from i but is some accumulated state, then the simplest thing is to extract that state into a custom class and to modify this state using void methods. In this example the generated void setCounter(int) method is used.

class Example {
    def static void main(String[] args) {
        println(generate)
    }

    def static generate() '''
        «var state = new State(0)»
        «FOR i : 0 ..< 10»
            Line Numnber: «i»
            «state.setCounter(state.counter + 1)»
        «ENDFOR»
    '''

}

class State {
    @Property
    var int counter

    new(int counter){
        this.counter = counter
    }
}
Stereometry answered 31/8, 2013 at 16:28 Comment(0)
S
10

In Xtend, everything is an expression, so «counter = counter + 1» evaluates to the result of the assignment, that's why it will be part of the string. So if you really want to perform a side effect in a template expression's for loop (which is strongly discouraged), do it in a block expression and return the empty string or null: «{ counter = counter + 1; "" }». Nevertheless, this is not too elegant, so you might want solve your problem in another way, as the other answers suggest.

Sleek answered 4/10, 2013 at 8:38 Comment(1)
Strange anyway, if I have to think about suppressing a behaviour which from a more technical point of view could be considered a side effect (even tough the side effect is by design in this case).Aman
S
3

In your example there is no use for counter. So it is hard to guess what your real usecase is. In most cases some calculation based on i is enought, eliminating counter completely. Orionll's answer is pointing in that direction.

If however counter is something which cannot be computed from i but is some accumulated state, then the simplest thing is to extract that state into a custom class and to modify this state using void methods. In this example the generated void setCounter(int) method is used.

class Example {
    def static void main(String[] args) {
        println(generate)
    }

    def static generate() '''
        «var state = new State(0)»
        «FOR i : 0 ..< 10»
            Line Numnber: «i»
            «state.setCounter(state.counter + 1)»
        «ENDFOR»
    '''

}

class State {
    @Property
    var int counter

    new(int counter){
        this.counter = counter
    }
}
Stereometry answered 31/8, 2013 at 16:28 Comment(0)
C
1
«var counter = 0»
«FOR i : 0 ..<10»
Line Number: «counter = i»
«ENDFOR»
Cassirer answered 24/8, 2013 at 9:38 Comment(1)
Nice and clean approach.Hager

© 2022 - 2024 — McMap. All rights reserved.