I want to do some funky closure-like stuff. I want a method to return an anonymous object whose guts make reference to the parameters of the method. Here is the code that I wrote that illustrates my intent:
object SessionManagement {
implicit class SessionManagementExtensions( val c : ChainBuilder ) {
def set( dest: String ) = object {
def from( src: String ) =
c.exec( session => {
val list = session( src ).as[Vector[String]]
val i = if ( list.size == 0 ) -1 else Random.nextInt( list.size )
val value = if ( i > 0 ) list(i) else "INVALID_" + dest
session.set( dest, value )
})
def to[T]( v: Expression[T] ) =
c.exec( session => session.set( dest, v ) )
}
}
What I'm TRYING to do is have a call to "set" return an object that allows me to then chain together a call to ".to", like so:
.set( SOMETHING ).to( OTHER )
But I can't say
def foo = object { ... }
Is there a way in Scala to get what I am after? Do I have to define a class and instantiate it?
Scala - Anonymous Functions. Scala supports first-class functions, which means functions can be expressed in function literal syntax, i.e., (x: Int) => x + 1, and that functions can be represented by objects, which are called function values.
An anonymous function is like a little mini-function. For example, given a list like this: You can create a new list by doubling each element in ints, like this: As that shows, doubledInts is now the list, List (2, 4, 6). In this example, this code is an anonymous function: _ * 2 This is a shorthand way of saying, “Multiply an element by 2.”
A function which does not contain a name is known as an anonymous function. An anonymous function provides a lightweight function definition. It is useful when we want to create an inline function.
Anonymous functions in source code are called function literals and at run time, function literals are instantiated into objects called function values. Scala supports first-class functions, which means functions can be expressed in function literal syntax, i.e., (x: Int) => x + 1, and that functions can be represented by...
You can simply return a new anonymous object. Your syntax was almost right: just replace object
by new
:
def set( dest: String ) = new {
def from( src: String ) =
...
def to[T]( v: Expression[T] ) =
...
}
However, this will give a structural type at call site, which will have to use reflection to use the methods. To prevent this, define a trait with the API of your object:
trait SetResult {
def from(src: String): ReturnTypeOfFrom
def to[T](v: Expression[T]): ReturnTypeOfTo
}
def set( dest: String ): SetResult = new SetResult {
def from( src: String ) =
...
def to[T]( v: Expression[T] ) =
...
}
Note that I used ReturnTypeOfFrom
and ReturnTypeOfSet
because I've no idea what your methods return. Btw, this is a bad habit: public methods should always have an explicit result type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With