0

I started learning groovy, and since I like learning by practice I have written that small app:

def height = 1; def commands; def floors; def finished = false

def up = { height < 5 ? height++ : println("Can't go higher!") }
def down = { height > -1 ? height-- : println("Can't go lower!") }
def help = { 
    print "Commands are " 
    commands.each{key, val -> print "'$key' "}
    println() 
}
def printFloors = {
    println "Floors are "
    floors.each{key,val -> println "'$key' -> '$val'"}
    println()
}
def exit = { finished = true }
def prompt = { print floors["$height"] }

commands = [ 'u': up, 
             'up': up,
             'd': down,
             'down': down,
             'help': help,
             '': help,
             'exit': exit,
             'pf': printFloors]

floors = [ "-1": "Basement : " ,
           "0": "Ground : " ,
           "5": "Penthouse : " ]
(1..4).each{floors += ["${it}" : "Floor ${it} : " ] }

bR = new BufferedReader(new InputStreamReader(System.in))

while(!finished){
    prompt()
    def cmd = bR.readLine()
    def code = commands[cmd]
    if(code != null){
        code()
    }
}

Everything works fine except printing on which floor you are (prompt function). It prints if you are in basement, ground floor or penthouse, but doesn't pick up "Floor i: " and prints null instead:/ When I type "pf" to print my floors dictionary, values are there... Any ideas? Thanks

Daniel Gruszczyk
  • 5,379
  • 8
  • 47
  • 86

1 Answers1

7

You're adding GString instances as keys in your map, then searching for them using String instances.

The two are not the same (despite having the same appearance -- see "GStrings aren't Strings" section on this page)

Try changing:

(1..4).each{floors += ["${it}" : "Floor ${it} : " ] }

to

(1..4).each{floors += [ ("${it}".toString()): "Floor ${it} : " ] }
tim_yates
  • 167,322
  • 27
  • 342
  • 338
  • An equivalent line would be: `(1..4).each{ floors[it as String] = "Floor ${it} : " }`. – epidemian Mar 14 '12 at 16:18
  • @epidemian I prefer: `floors << (1..4)*.toString().collectEntries { [ (it) : "Floor ${it} : " ] }` ;-) – tim_yates Mar 14 '12 at 16:31
  • @tim_yates Yeah, I would prefer that too. And probably replace `(1..4)*.toString()` with `('1'..'4')` hehe. – epidemian Mar 14 '12 at 17:23
  • 1
    @epidemian I though about `('1'..'4')`, but decided it might cause issues when they get round to finishing the 10th floor ;-) – tim_yates Mar 14 '12 at 17:27