I have a utility object SideEffects, which is passed to a function as implicit argument. It collects all non-db effects to run if my db transaction was successed.
def someDbAction(implicit se: SideEffects) {
...
se.add {doSomethingNonDbLike()}
...
}
The simple way to use this util is to write something like this:
implicit val se = new SideEffects()
db.run(someDbAction().transactionally).flatMap(se.run)
And I want to write something like this:
SideEffects.run {
someDbAction()
}
Is it possible to do it? Just can't make it work.
I don't understand why your someDbAction (or anything at all for that matter!) needs implicit parameter.
Going by your "I want to write ...", it looks like you want this:
object SideEffects() {
val se = new SideEffects
def run[T](action: => T) =
db.run(action).transactionally.flatMap(se.run())
}
Then SideEffects.run { someDbAction() } (or just SideEffects.run(someDbAction)) does exactly what you wanted.
Related
I have object
object func1{
def something(arg1: Int): String{
// var date = something2()
// Using date
}
def something2(): LocalDate{
LocalDate.now()
}
}
I want to write a test on something method, How can I mock something2
You can't make static methods. So, you need to do something like this:
def something(val now: () => Date = LocalDate.now) = ...
Then, in your production code, you do val foo = something() as you normally would, but in your test, you can do things like
something(_ => new Date(0l)) shouldBe foo
or
val date = mock[Function0[Date]]
when(date.apply()).thenReturn(new Date(0l))
something(date) shouldBe foo
If the code's functionality depends on the time, it's definitely recommended that you have a second look at the code you're testing and explicitly pass a Clock as a parameter or something along those lines (e.g. a function as suggested in other comments) to make its behavior easy to test.
If you are testing this to make sure that a field somewhere indeed contains the time returned by LocalDate.now() please consider that you might be testing the behavior of LocalDate rather than your own code's, so probably mocking that doesn't really give you anything.
If timing is fundamental to the function's behavior and you have no control over it, I believe you might somehow use Mockito's ability to mock static objects. I came up with the following which compiles, but I'm not sure about whether it works or not (since I believe it relies on some bytecode manipulation black magic which might make your testing suite brittle, so beware):
import scala.util.{Try, Using}
import java.time.{Clock, Instant, LocalDate, ZoneId}
import org.mockito.Mockito._
def withClock[A](clock: Clock)(f: => Unit): Try[Unit] = {
Using(mockStatic(classOf[LocalDate])) { mocked =>
mocked.when(() => LocalDate.now()).thenReturn(LocalDate.now(clock))
f
}
}
withClock(Clock.fixed(Instant.ofEpochMilli(42), ZoneId.of("UTC"))) {
assert(LocalDate.now().toEpochDay() == 0)
}
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).
When you see code that follows this pattern:
def index = Action { request =>
// ..
}
Action trait: https://github.com/playframework/playframework/blob/master/framework/src/play/src/main/scala/play/api/mvc/Action.scala#L65
When looking at this code, how would you know that the request object is available to use within the code block? (is there a intellij shortcut for this?)
Can someone please create a miniature example of where you can mimic this pattern so I can understand how this works, and if you can explain in technical terms what is going on?
The Action trait is not of interest here. Instead, because the body of the index method must be a value, not a type, you are looking at the Action object. You can learn more about objects here. Let's first simplify the syntax by removing syntactic sugar, i.e. making the program behave the same but with simpler constructs. If you try to call an object as if it were a method, what really happens is that .apply is inserted for you by the compiler:
def index = Action.apply((request) => {
// ..
})
This may be more familiar; the apply method is being called on the Action object, passing a lambda function that takes a request. And obviously, an argument to a lambda is always available within that lambda. That's the point of them.
The lambda in this case is also known as a callback. A simple example that clarifies these features follows:
object WithAnswer {
def apply(f: Int => Unit): Unit =
f(42)
}
def printAnswer() = WithAnswer { answer =>
println(answer)
}
This is called as Loan pattern
withWriter creates a writer for the user and then ensures the resource (writer) is properly closely after using.
All that user has to do is just use the writer and write something to the file
def withWriter(file: File)(f: Writer => Unit): Unit = {
val writer = new PrintWriter(file)
try {
f(writer)
} finally {
writer close
}
}
Usage:
withWriter(new File("some_fix.txt") { writer =>
writer println("write something")
}
I usually use Scala with SLF4J through the Loggable wrapper in LiftWeb. This works decently well with the exception of the quite common method made up only from 1 chain of expressions.
So if you want to add logging to such a method, the simply beautiful, no curly brackets
def method1():Z = a.doX(x).doY(y).doZ()
must become:
def method1():Z = {
val v = a.doX(x).doY(y).doZ()
logger.info("the value is %s".format(v))
v
}
Not quite the same, is it? I gave it a try to solve it with this:
class ChainableLoggable[T](val v:T){
def logInfo(logger:Logger, msg:String, other:Any*):T = {
logger.info(msg.format(v, other))
v
}
}
implicit def anyToChainableLogger[T](v:T):ChainableLoggable[T] = new ChainableLoggable(v)
Now I can use a simpler form
def method1():Z = a.doX(x).doY(y).doZ() logInfo(logger, "the value is %s")
However 1 extra object instantiation and an implicit from Any starts to look like a code stink.
Does anyone know of any better solution? Or maybe I shouldn't even bother with this?
Scala 2.10 has just a solution for you - that's a new feature Value Class which allows you to gain the same effect as the implicit wrappers provide but with no overhead coming from instantiation of those wrapper classes. To apply it you'll have to rewrite your code like so:
implicit class ChainableLoggable[T](val v : T) extends AnyVal {
def logInfo(logger:Logger, msg:String, other:Any*) : T = {
logger.info(msg.format(v, other))
v
}
}
Under the hood the compiler will transform the logInfo into an analogue of Java's common "util" static method by prepending your v : T to it's argument list and updating its usages accordingly - see, nothing gets instantiated.
That looks like the right way to do it, especially if you don't have the tap implicit around (not in the standard library, but something like this is fairly widely used--and tap is standard in Ruby):
class TapAnything[A](a: A) {
def tap(f: A => Any): A = { f(a); a }
}
implicit def anything_can_be_tapped[A](a: A) = new TapAnything(a)
With this, it's less essential to have the info implicit on its own, but if you use it it's an improvement over
.tap(v => logger.info("the value is %s".format(v)))
If you want to avoid using implicits, you can define functions like this one in your own logging trait. Maybe not as pretty as the solution with implicits though.
def info[A](a:A)(message:A=>String) = {
logger.info(message(a))
a
}
info(a.doX(x).doY(y).doZ())("the value is " + _)
I'm writing a Scala application that accesses a database. Most of the time, there will be a connection available, but sometimes there won't be. What I'd like to do is something like the following:
object User {
def authenticate(username: String, password: String)
(implicit conn: Connection): Option[User] = {
// use conn to grab user from db and check that password matches
// return Some(user) if so, None if not
}
def authenticate(username: String, password: String): Option[User] = {
implicit val conn = DB.getConnection()
authenticate(username, password)
}
}
What I hoped would happen is that, if there's an implicit value of type Connection available, the compiler would use the first method. If not, it would use the second. Unfortunately, I've discovered that the compiler isn't quite that smart or, if it is, I'm not telling it what to do in the right way.
So, my basic question is, is there a way to write a method that expects an implicit argument and then provide an overloaded version of the same method that creates an acceptable value of the implicit parameter's type if there isn't one available.
You might say, "Why would you want to do such a thing? If you can create an acceptable value of the appropriate type, why not just always do it?" And that's mostly true, except that if I have an open database connection, I'd prefer to go ahead and use it rather than creating a new one. However, if I don't have an open database connection, I know where to get one.
I mean, the simple answer is to just give the two methods different names, but I shouldn't have to, gosh-darn-it. But maybe I do...
Thanks!
Todd
You don't need overloaded methods. Just give your implicit parameter a default value, i.e.
object User {
def authenticate(username:String, password:String)(implicit conn:Connection = null): Option[User] = {
val real_conn = Option(conn).getOrElse(DB.getConnection())
// do the rest with the real_conn
}
}
The cleaner solution which I can think of is using nested methods and as someone suggested, default values for implicits.
class Testclass {
def myMethod(a:Int)(implicit b:Option[Int]=None):Int = {
def myMethodInternal(a:Int, b:Int):Int = {
// do something
a+b
}
val toUse = b.getOrElse(30)
myMethodInternal(a,toUse)
}
}
Inside your method you define an myMethodInternal, which takes no implicits but only explicits parameters. This method will be visible only inside myMethod, and you will prepare your second parameter like the following:
val toUse = b.getOrElse(30)
And finally call your method with explicits parameters:
myMethodInternal(a,toUse)