Gareth
Gareth

Reputation: 5719

Storing an anonymous function passed as a parameter in a Map

I'm trying to implement a simple web application server as a personal project to improve my Scala, but I've hit upon a problem.

I'd like to be able to set up routes using code like the following:

def routes()
{
    get("/wobble")
    {
        ...many lines of code here...
    }

    get("/wibble")
    {
        ...many lines of code here...
    }

    post("/wibble")
    {
        ...many lines of code here...
    }

    post("/wobble")
    {
        ...many lines of code here...
    }
}

routes is called by the server when it starts and get and post are functions defined by me like this:

get(url:String)(func:()=>String)=addroute("GET",url,func)
post(url:String(func:()=>String)=addroute("POST",url,func)

addroute(method:String,url:String,f:()=>String)
{
    routesmap+=(method->Map[String,()=>String](url,func))
}

Unfortunately, I've had nothing but problems with this. Could anyone tell me the correct way in Scala to add an anonymous function (as passed in as a parameter in the defined routes function above) to a Map (or any other Scala collection for that matter)?

Upvotes: 1

Views: 267

Answers (3)

fp4me
fp4me

Reputation: 463

May be, this one ? :

type Fonc = ( (=> String) => Unit)

var routesmap = Map[String,Map[String,()=>String]]()

def addRoute(method:String,url:String,f:()=>String) = {     

routesmap+=(method-> (routesmap.getOrElse(method,Map[String,()=>String]()) + (url->f)))

}

def get(url:String):Fonc = (x => addRoute("GET",url,() => x))
def post(url:String):Fonc = (x => addRoute("POST",url,() => x))

def routes() 
{
post("/wobble")
{
"toto"
}

get("/wibble")
{
"titi"
}

}

Upvotes: 1

fp4me
fp4me

Reputation: 463

you can try this code :

def addRoute(method:String,url:String,f:()=>String) = {     

routesmap+=(method-> (routesmap.getOrElse(method,Map[String,()=>String]()) + (url->f)))

}

def get(url:String,func:()=>String)= addRoute("GET",url,func) 

def post(url:String,func:()=>String)= addRoute("POST",url,func)


def routes() 
{
get("/wobble",()=>{"toto"})
get("/wibble",()=>{println("test")
                   "titi"})
}

and execute these commands

scala> routes
scala> routesmap.get("GET").get("/wibble")()

Upvotes: 1

paradigmatic
paradigmatic

Reputation: 40461

Here is a working example:

scala> var funcs = Map[String,(Int)=>Int]()
funcs: scala.collection.immutable.Map[String,Int => Int] = Map()

scala> funcs += ("time10", i => i * 10 )

scala> funcs += ("add2", i => i + 2 )

scala> funcs("add2")(3)
res3: Int = 5

scala> funcs("time10")(10)
res4: Int = 100

You can also add a declared function:

val minus5 = (i:Int) => i - 5
funcs += ( "minus5", minus5)

Or a method:

def square(i: Int) = i*i
funcs += ("square", square)

In your case, you can have two maps, one for GET and one for POST. It should simplify the design (and at most, you will end with four maps if you include DEL and PUT).

Upvotes: 2

Related Questions