Modifying value returned from a method in Scala (Highcharts lib) - scala

I am using an external library in Scala, which uses a set of traits to pass around complex configuration options to different methods. This is Highcharts Scala API, but the problem seems to be more general.
The library defines a trait (HighchartsOptions in the actual usage), which is just a data transfer object that stores a number of fields and allows them to be passed around. Code simplified and generalized for clarity looks like this:
trait Opts {
def option1: Int = 3
def option2: String = "abc"
//Many more follow, often of more complex types
}
As long as the complete set of options can be generated in one place, this allows for a neat syntax:
val opts = new Opts() {
override val option1 = 5
//And so on for more fields
}
doSomething(opts)
However, there are a few situations where one piece of code prepares such a configuration but another piece of code needs to adjust just one option extra. It would be nice to be able to pass some Opts instance to a method and let the method modify a value or two.
Since the original trait is based on defs rather than vars, it's easy to override an option's value only if the type of the object is known, like in the example above. If a method receives only an instance of some anonymous subclass of Opts, how can it create another instance or modify the received one so that a call to e.g. option2 could return a different value? The desired operation is similar to what Mockito's spy does, however I feel there should be some less contrived way than using a mocking framework to achieve this effect.
PS: Actually I am a bit surprised by the use of such an interface by the library's authors, so perhaps I'm missing something and there is some completely different way of achieving my goal of building a single set of options from several different places in the code (e.g. some builder object that is mutable and that I can pass around instead of the finished HighchartsOptions)?

I would first check if using the Opts trait (solely) is an absolute necessity. Hopefully it's not and then you just extend the trait, overriding defs with vars, like you said.
When Opts is mandatory and you have its instance that you want to copy modifying some fields, here's what you could do:
Write a wrapper for Opts, which extends Opts, but delegates every call to the wrapped Opts excluding the fields that you want to modify. Set those fields to values you want.
Writing the wrapper for a broad-interface trait can be boring task, therefore you may consider using http://www.warski.org/blog/2013/09/automatic-generation-of-delegate-methods-with-macro-annotations/ to let macros generate most of it automatically.

The shortest, simplest way.
Define a case class:
case class Options(
option1: Int,
option2: String
/* ... */
) extends Opts
and implicit conversion from Opts to your Options
object OptsConverter {
implicit def toOptions(opts: Opts) = Options(
option1 = opts.option1,
option2 = opts.option2
/* ... */
)
}
That way you get all copy methods (generated by compiler) for free.
You can use it like that:
import OptsConverter.toOptions
def usage(opts: Opts) = {
val improvedOpts = opts.copy(option2 = "improved")
/* ... */
}
Note, that Options extends Opts, so you can use it whenever Opts is required. You'll be able to call copy to obtain a modified instance of Opts in every place where you import the implicit conversion.

The simplest solution is to allow the trait to define it's own "copy" method, and allow it's subclasses (or even base class) to work with that. However, the parameters can really only match the base class unless you recast it later. Incidentally this doesn't work as "mixed in" so your root might as well be an abstract class, but it works the same way. The point of this is that the subclass type keeps getting passed along as it's copied.
(Sorry I typed this without a compiler so it may need some work)
trait A {
type myType<:A
def option1: Int
def option2: String
def copyA(option1_:Int=option1, option2_String=option2):myType = new A {
def option1 = option_1
def option2 = option_2
}
}
trait B extends A { me=>
type myType = B
def option3: Double
//callable from A but properly returns B
override def copyA(option1_:Int=option1, option2_:String=option2):myType = new B {
def option1 = option_1
def option2 = option_2
def option3 = me.option3
}
//this is only callable if you've cast to type B
def copyB(option1_:Int=option1, option2_:String=option2, option3_:Double=option3):myType = new B {
def option1 = option_1
def option2 = option_2
def option3 = option_3
}
}

Related

DSL : shortcut to apply a function on every element of a collection of a specific type

I'm new to scala and I'm trying to use its great capacities to create a simple DSL. I found that it was possible to create something like the example below when using DSL and I was wondering how it was possible:
val oranges = Array.tabulate(2)(i => Orange(i+10)) //Orange(diameter)
// Oranges of diameter 10 and 11
oranges incDiameter 5
// Oranges in the array now have diameter 15 and 16
What I don't understand is how we can directly apply the incDiameter function on an array, since we cannot add the function incDiameter to the Array scala class; for my understandings it is equivalent as doing oranges.incDiameter(5) so something like Array[Fruit].incDiameter(5), but since incDiameter is not declared in the Array class, where should it be declared in order for the 3rd line to work ?
My intuition is that there's probably a way to modify how functions apply on iterables of our own classes so the 3rd line of the exemple is in fact converted to oranges.map(_.incDiameter(5)) but I've never saw that anywhere
Extension methods:
implicit class OrangesOps(val oranges: Array[Orange]) extends AnyVal {
def incDiameter(by: Int): Array[Orange] = oranges.map(_.incDiameter(5))
}
if you want that extension method to be applicable to any type that you can prove is applicable, you can use type classes:
trait IncreasableDiameter[A] {
def incDiamater(what: A)(by: Int): A
}
implicit class DiamatersOps[A](val what: A) extends AnyVal {
def incDiameter(by: Int)(implicit increasable: IncreasableDiameter[A]): A =
increasable.incDiamater(what)(by)
}
then, if you can provide an implicit proof that there is an instance of a type class for your type, you would be able to use the incDiameter method (as long as both instance and extension methods will be defined/imported into the scope)
implicit val orangesIncreasable: IncreasableDiameter[Orange] =
new IncreasableDiameter[Orange] {
def incDiamater(what: Orange)(by: Int): Orange = what.incDiamater(by)
}
implicit def arrayIncreasable[A](
implicit increasable: IncreasableDiameter[A]
): IncreasableDiameter[Array[A]] = new IncreasableDiameter[Array[A]] {
def incDiamater(what: Array[A])(by: Int): Array[A] = what.map(_.incDiamater(by))
}
This would let you call this operation on:
val orange: Orange = ...
orange.incDiameter(5) // oranges built-in method
Array(orange).incDiameter(5) // no build in method, but extension method can be used
// because we can produce type class for Array[Orange]
Array(Array(orange)).incDiameter(5) // similar to above, we can create
// type class for Array[Array[Orange]]
Depending on how much flexibility you need, you can use simple extension method, or
- if you want to be able to use them with many more types and generate implementation
basing on some principles - with a type class. For starters try the former, and only if you will need extensibility go for the latter. If you want to know more learn more about: implicits, extension methods and type classes.

Can Scala infer the actual type from the return type actually expected by the caller?

I have a following question. Our project has a lot of code, that runs tests in Scala. And there is a lot of code, that fills the fields like this:
production.setProduct(new Product)
production.getProduct.setUuid("b1253a77-0585-291f-57a4-53319e897866")
production.setSubProduct(new SubProduct)
production.getSubProduct.setUuid("89a877fa-ddb3-3009-bb24-735ba9f7281c")
Eventually, I grew tired from this code, since all those fields are actually subclasses of the basic class that has the uuid field, so, after thinking a while, I wrote the auxiliary function like this:
def createUuid[T <: GenericEntity](uuid: String)(implicit m : Manifest[T]) : T = {
val constructor = m.runtimeClass.getConstructors()(0)
val instance = constructor.newInstance().asInstanceOf[T]
instance.setUuid(uuid)
instance
}
Now, my code got two times shorter, since now I can write something like this:
production.setProduct(createUuid[Product]("b1253a77-0585-291f-57a4-53319e897866"))
production.setSubProduct(createUuid[SubProduct]("89a877fa-ddb3-3009-bb24-735ba9f7281c"))
That's good, but I am wondering, if I could somehow implement the function createUuid so the last bit would like this:
// Is that really possible?
production.setProduct(createUuid("b1253a77-0585-291f-57a4-53319e897866"))
production.setSubProduct(createUuid("89a877fa-ddb3-3009-bb24-735ba9f7281c"))
Can scala compiler guess, that setProduct expects not just a generic entity, but actually something like Product (or it's subclass)? Or there is no way in Scala to implement this even shorter?
Scala compiler won't infer/propagate the type outside-in. You could however create implicit conversions like:
implicit def stringToSubProduct(uuid: String): SubProduct = {
val n = new SubProduct
n.setUuid(uuid)
n
}
and then just call
production.setSubProduct("89a877fa-ddb3-3009-bb24-735ba9f7281c")
and the compiler will automatically use the stringToSubProduct because it has applicable types on the input and output.
Update: To have the code better organized I suggest wrapping the implicit defs to a companion object, like:
case class EntityUUID(uuid: String) {
uuid.matches("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}") // possible uuid format check
}
case object EntityUUID {
implicit def toProduct(e: EntityUUID): Product = {
val p = new Product
p.setUuid(e.uuid)
p
}
implicit def toSubProduct(e: EntityUUID): SubProduct = {
val p = new SubProduct
p.setUuid(e.uuid)
p
}
}
and then you'd do
production.setProduct(EntityUUID("b1253a77-0585-291f-57a4-53319e897866"))
so anyone reading this could have an intuition where to find the conversion implementation.
Regarding your comment about some generic approach (having 30 types), I won't say it's not possible, but I just do not see how to do it. The reflection you used bypasses the type system. If all the 30 cases are the same piece of code, maybe you should reconsider your object design. Now you can still implement the 30 implicit defs by calling some method that uses reflection similar what you have provided. But you will have the option to change it in the future on just this one (30) place(s).

Value to indicate to use default

In Scala I would like to have something like this
TokenizerExample.scala
class TokenizerExample private (whateva : Any)(implicit val separator : Char = '.') {
def this(data2Tokenize : String)(implicit s : Char) {
this("", s) //call to base constructor
}
def this(data2Tokenize : Array[Char])(implicit s : Char) { {
this("", s) //call to base constructor
}
}
what I would like to achieve is to allow the user to call any of the two public constructors either providing or not the separator, but if they do NOT provide the separator automatically take the one in the base constructor, I was wondering if there is a value that I can pass to the base constructor so that scala use the default on the private base constructor.
what I would like to avoid it to do the next in each constructor
def this(_3rdConstructor : SytringBuilder)(implicit s : Char = '.') ...
I tried this in many different ways, with the values being implicit, with the separator as a Option, but I do not get a result that I actually like, specially because scala complains about having implicit values in multiple constructors (which kind of defeats the purpose of having them). Is there a way to achieve that behavior in a nice way without
1) forcing the user to provide a separator.
2) go into "bad-practices" by passing null values and then validating them (specially because that would not allow my separator to be a val in the constructor.
3) creating YET ANOTHER LANGUAGE just because I dislike a small little thing about one of them :) .
I would strongly advice you against using implicits for this purpose. The resolution rules are rather complex, and it makes the code extremely hard to follow, because it is almost impossible to tell what value the constructor will end up receiving without the debugger.
If all you are trying to do is avoid defining the default in multiple places, just define it in a companion object:
object Foo {
val defaultParam = ','
}
class Foo {
import Foo.defaultParam
def this(data: String, param: Char = defaultParam) = ???
def this(data: List[Char], param: Char = defaultParam) = ???
// etc ...
}
If you insist on using implicits, you can use a similar approach to the above: just make defaultParam definition implicit, drop the defaults, replacing them with implicit lists, and then import Foo._ in scope where you are making the call. But, really, don't do that: it adds no value, and only has disadvantages in this case.

Optional boolean parameters in Scala

I've been lately working on the DSL-style library wrapper over Apache POI functionality and faced a challenge which I can't seem to good solution for.
One of the goals of the library is to provide user with ability to build a spreadsheet model as a collection of immutable objects, i.e.
val headerStyle = CellStyle(fillPattern = CellFill.Solid, fillForegroundColor = Color.AquaMarine, font = Font(bold = true))
val italicStyle = CellStyle(font = Font(italic = true))
with the following assumptions:
User can optionally specify any parameter (that means, that you can create CellStyle with no parameters as well as with the full list of explicitly specified parameters);
If the parameter hasn't been specified explicitly by the user it is considered undefined and the default environment value (default value for the format we're converting to) will be used;
The 2nd point is important, as I want to convert this data model into multiple formats and i.e. the default font in Excel doesn't have to be the same as default font in HTML browser (and if user doesn't define the font family explicitly I'd like him to see the data using those defaults).
To deal with the requirements I've used the variation of the null pattern described here: Pattern for optional-parameters in Scala using null and also suggested here Scala default parameters and null (below a simplified example).
object ModelObject {
def apply(modelParam : String = null) : ModelObject = ModelObject(
modelParam = Option(modelParam)
)
}
case class ModelObject private(modelParam : Option[String])
Since null is used only internally in the companion object and very localized I decided to accept the null-sacrifice for the sake of the simplicity of the solution. The pattern works well with all the reference classes.
However for Scala primitive types wrappers null cannot be specified. This is especially a huge problem with Boolean for which I effectively consider 3 states (true, false and undefined). Wanting to provide the interface, where user still be able to write bold = true I decided to reach to Java wrappers which accept nulls.
object ModelObject {
def apply(boolParam : java.lang.Boolean = null) : ModelObject = ModelObject(
boolParam = Option(boolParam).map(_.booleanValue)
)
}
case class ModelObject private(boolParam : Option[Boolean])
This however doesn't right and I've been wondering whether there is a better approach to the problem. I've been thinking about defining the union types (with additional object denoting undefined value): How to define "type disjunction" (union types)?, however since the undefined state shouldn't be used explicitly the parameter type exposed by IDE to the user, it is going to be very confusing (ideally I'd like it to be Boolean).
Is there any better approach to the problem?
Further information:
More DSL API examples: https://github.com/norbert-radyk/spoiwo/blob/master/examples/com/norbitltd/spoiwo/examples/quickguide/SpoiwoExamples.scala
Sample implementation of the full class: https://github.com/norbert-radyk/spoiwo/blob/master/src/main/scala/com/norbitltd/spoiwo/model/CellStyle.scala
You can use a variation of the pattern I described here: How to provide helper methods to build a Map
To sum it up, you can use some helper generic class to represent optional arguments (much like an Option).
abstract sealed class OptArg[+T] {
def toOption: Option[T]
}
object OptArg{
implicit def autoWrap[T]( value: T ): OptArg[T] = SomeArg(value)
implicit def toOption[T]( arg: OptArg[T] ): Option[T] = arg.toOption
}
case class SomeArg[+T]( value: T ) extends OptArg[T] {
def toOption = Some( value )
}
case object NoArg extends OptArg[Nothing] {
val toOption = None
}
You can simply use it like this:
scala>case class ModelObject(boolParam: OptArg[Boolean] = NoArg)
defined class ModelObject
scala> ModelObject(true)
res12: ModelObject = ModelObject(SomeArg(true))
scala> ModelObject()
res13: ModelObject = ModelObject(NoArg)
However as you can see the OptArg now leaks in the ModelObject class itself (boolParam is typed as OptArg[Boolean] instead of Option[Boolean].
Fixing this (if it is important to you) just requires to define a separate factory as you have done yourself:
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class ModelObject private(boolParam: Option[Boolean])
object ModelObject {
def apply(boolParam: OptArg[Boolean] = NoArg): ModelObject = new ModelObject(
boolParam = boolParam.toOption
)
}
// Exiting paste mode, now interpreting.
defined class ModelObject
defined module ModelObject
scala> ModelObject(true)
res22: ModelObject = ModelObject(Some(true))
scala> ModelObject()
res23: ModelObject = ModelObject(None)
UPDATE The advantage of using this pattern, over simply defining several overloaded apply methods as shown by #drexin is that in the latter case the number of overloads grows very fast with the number of arguments(2^N). If ModelObject had 4 parameters, that would mean 16 overloads to write by hand!

Scala dependency injection: alternatives to implicit parameters

Please pardon the length of this question.
I often need to create some contextual information at one layer of my code, and consume that information elsewhere. I generally find myself using implicit parameters:
def foo(params)(implicit cx: MyContextType) = ...
implicit val context = makeContext()
foo(params)
This works, but requires the implicit parameter to be passed around a lot, polluting the method signatures of layer after layout of intervening functions, even if they don't care about it themselves.
def foo(params)(implicit cx: MyContextType) = ... bar() ...
def bar(params)(implicit cx: MyContextType) = ... qux() ...
def qux(params)(implicit cx: MyContextType) = ... ged() ...
def ged(params)(implicit cx: MyContextType) = ... mog() ...
def mog(params)(implicit cx: MyContextType) = cx.doStuff(params)
implicit val context = makeContext()
foo(params)
I find this approach ugly, but it does have one advantage though: it's type safe. I know with certainty that mog will receive a context object of the right type, or it wouldn't compile.
It would alleviate the mess if I could use some form of "dependency injection" to locate the relevant context. The quotes are there to indicate that this is different from the usual dependency injection patterns found in Scala.
The start point foo and the end point mog may exist at very different levels of the system. For example, foo might be a user login controller, and mog might be doing SQL access. There may be many users logged in at once, but there's only one instance of the SQL layer. Each time mog is called by a different user, a different context is needed. So the context can't be baked into the receiving object, nor do you want to merge the two layers in any way (like the Cake Pattern). I'd also rather not rely on a DI/IoC library like Guice or Spring. I've found them very heavy and not very well suited to Scala.
So what I think I need is something that lets mog retrieve the correct context object for it at runtime, a bit like a ThreadLocal with a stack in it:
def foo(params) = ...bar()...
def bar(params) = ...qux()...
def qux(params) = ...ged()...
def ged(params) = ...mog()...
def mog(params) = { val cx = retrieveContext(); cx.doStuff(params) }
val context = makeContext()
usingContext(context) { foo(params) }
But that would fall as soon as asynchronous actor was involved anywhere in the chain. It doesn't matter which actor library you use, if the code runs on a different thread then it loses the ThreadLocal.
So... is there a trick I'm missing? A way of passing information contextually in Scala that doesn't pollute the intervening method signatures, doesn't bake the context into the receiver statically, and is still type-safe?
The Scala standard library includes something like your hypothetical "usingContext" called DynamicVariable. This question has some information about it When we should use scala.util.DynamicVariable? . DynamicVariable does use a ThreadLocal under the hood so many of your issues with ThreadLocal will remain.
The reader monad is a functional alternative to explicitly passing an environment http://debasishg.blogspot.com/2010/12/case-study-of-cleaner-composition-of.html. The Reader monad can be found in Scalaz http://code.google.com/p/scalaz/. However, the ReaderMonad does "pollute" your signatures in that their types must change and in general monadic programming can cause a lot of restructuring to your code plus extra object allocations for all the closures may not sit well if performance or memory is a concern.
Neither of these techniques will automatically share a context over an actor message send.
A little late to the party, but have you considered using implicit parameters to your classes constructors?
class Foo(implicit biz:Biz) {
def f() = biz.doStuff
}
class Biz {
def doStuff = println("do stuff called")
}
If you wanted to have a new biz for each call to f() you could let the implicit parameter be a function returning a new biz:
class Foo(implicit biz:() => Biz) {
def f() = biz().doStuff
}
Now you simply need to provide the context when constructing Foo. Which you can do like this:
trait Context {
private implicit def biz = () => new Biz
implicit def foo = new Foo // The implicit parameter biz will be resolved to the biz method above
}
class UI extends Context {
def render = foo.f()
}
Note that the implicit biz method will not be visible in UI. So we basically hide away those details :)
I wrote a blog post about using implicit parameters for dependency injection which can be found here (shameless self promotion ;) )
I think that the dependency injection from lift does what you want. See the wiki for details using the doWith () method.
Note that you can use it as a separate library, even if you are not running lift.
You asked this just about a year ago, but here's another possibility. If you only ever need to call one method:
def fooWithContext(cx: MyContextType)(params){
def bar(params) = ... qux() ...
def qux(params) = ... ged() ...
def ged(params) = ... mog() ...
def mog(params) = cx.doStuff(params)
... bar() ...
}
fooWithContext(makeContext())(params)
If you need all the methods to be externally visible:
case class Contextual(cx: MyContextType){
def foo(params) = ... bar() ...
def bar(params) = ... qux() ...
def qux(params) = ... ged() ...
def ged(params) = ... mog() ...
def mog(params) = cx.doStuff(params)
}
Contextual(makeContext()).foo(params)
This is basically the cake pattern, except that if all your stuff fits into a single file, you don't need all the messy trait stuff to combine it into one object: you can just nest them. Doing it this way also makes cx properly lexically scoped, so you don't end up with funny behavior when you use futures and actors and such. I suspect that if you use the new AnyVal, you could even do away with the overhead of allocating the Contextual object.
If you want to split your stuff into multiple files using traits, you only really need a single trait per file to hold everything and put the MyContextType properly in scope, if you don't need the fancy replaceable-components-via-inheritance thing most cake pattern examples have.
// file1.scala
case class Contextual(cx: MyContextType) with Trait1 with Trait2{
def foo(params) = ... bar() ...
def bar(params) = ... qux() ...
}
// file2.scala
trait Trait1{ self: Contextual =>
def qux(params) = ... ged() ...
def ged(params) = ... mog() ...
}
// file3.scala
trait Trait2{ self: Contextual =>
def mog(params) = cx.doStuff(params)
}
// file4.scala
Contextual(makeContext()).foo(params)
It looks kinda messy in a small example, but remember, you only need to split it off into a new trait if the code is getting too big to sit comfortable in one file. By that point your files are reasonably big, so an extra 2 lines of boilerplate on a 200-500 line file is not so bad really.
EDIT:
This works with asynchronous stuff too
case class Contextual(cx: MyContextType){
def foo(params) = ... bar() ...
def bar(params) = ... qux() ...
def qux(params) = ... ged() ...
def ged(params) = ... mog() ...
def mog(params) = Future{ cx.doStuff(params) }
def mog2(params) = (0 to 100).par.map(x => x * cx.getSomeValue )
def mog3(params) = Props(new MyActor(cx.getSomeValue))
}
Contextual(makeContext()).foo(params)
It Just Works using nesting. I'd be impressed if you could get similar functionality working with DynamicVariable.
You'd need a special subclass of Future that stores the current DynamicVariable.value when created, and hook into the ExecutionContext's prepare() or execute() method to extract the value and properly set up the DynamicVariable before executing the Future.
Then you'd need a special scala.collection.parallel.TaskSupport to do something similar in order to get parallel collections working. And a special akka.actor.Props in order to do something similar for that.
Every time there's a new mechanism of creating asynchronous tasks, DynamicVariable based implementations will break and you'll have weird bugs where you end up pulling up the wrong Context. Every time you add a new DynamicVariable to keep track of, you'll need to patch all your special executors to properly set/unset this new DynamicVariable. Using nesting you can just let lexical closure take care of all of this for you.
(I think Futures, collections.parallel and Props count as "layers in between that aren't my code")
Similar to the implicit approach, with Scala Macros you can do auto-wiring of objects using constructors - see my MacWire project (and excuse the self-promotion).
MacWire also has scopes (quite customisable, a ThreadLocal implementation is provided). However, I don't think you can propagate context across actor calls with a library - you need to carry some identifier around. This can be e.g. through a wrapper for sending actor messages, or more directly with the message.
Then as long as the identifier is unique per request/session/whatever your scope is, it's just a matter of looking things up in a map via a proxy (like the MacWire scopes do, the "identifier" here isn't needed as it is stored in the ThreadLocal).