Reputation: 47051
I saw codes below from this Link
abstract class SessionFactory {
protected[squery] def createConnection(): Connection
def createSession(): Session = new Session(this)
def withSession[T](f: Session => T): T = {
val s = createSession()
try { f(s) } finally s.close()
}
def withSession[T](f: => T): T =
withSession { s: Session => SessionFactory.dyn.withValue(s)(f) }
}
object SessionFactory {
private val dyn = new DynamicVariable[Session](null)
implicit def getThreadSession: Session = {
val s = dyn.value
if(s eq null)
throw new SQLException("No implicit thread session available; getThreadSession() can only be used within a withSession block")
else s
}
}
I don't know how could def withSession[T](f: => T): T
get the value for s:Session
, so I tried to reproduce this usage of implicit
in a simple snippet:
class printTest {
def printWithParameter(s:String) = println(s)
def printWithImplicit = printWithParameter(s:String)
}
object printTest {
implicit val sp:String = "implicit value"
implicit def getString:String = "implicit def"
}
val pt = new printTest()
pt.printWithImplicit
But the printTest
doesn't work, the compiler says:
Error:(3, 47) not found: value s
def printWithImplicit = printWithParameter(s:String)
^
Does anyone have ideas about this?
Upvotes: 0
Views: 168
Reputation: 297195
You have been misled. The implicit is not being used, because that method is not getting a value for Session
. Let's review it:
def withSession[T](f: => T): T =
withSession { s: Session => SessionFactory.dyn.withValue(s)(f) }
So, it takes an f
of type T
, passed by-name (that is, it is evaluated when used, not when withSession
is called). It then calls withSession
passing a function from Session
to T
. It does not create a Session
, it asks for a Session
, so to speak. So let's see what it called:
def withSession[T](f: Session => T): T = {
val s = createSession()
try { f(s) } finally s.close()
}
Here it takes a function from Session
to T
(which is going to be s: Session => SessionFactory.dyn.withValue(s)(f)
), creates a Session
, and then use that session to invoke the function that was passed. The session creation is just a new Session(this)
, so nowhere is there any implicit being used.
Upvotes: 2
Reputation: 3512
This reason you get
Error:(3, 47) not found: value s
def printWithImplicit = printWithParameter(s:String)
^
is because you defined a function called printWithImplicit
which takes no parameter and return Unit
. It can be explicitly written as: def printWithImplicit(): Unit
Since it takes no parameters, so its function body, in this case, printWithParameter(s:String)
, find no definition of s
Back to your question.
You need to import printTest.sp
before
val pt = new printTest()
pt.printWithImplicit
I stripped your example down a bit:
class printTest {
def printWithParameter(s:String) = println(s)
def printWithImplicit(implicit s:String) = printWithParameter(s)
}
object printTest {
implicit val sp:String = "implicit value"
}
import printTest.sp
val pt = new printTest()
pt.printWithImplicit
Upvotes: 2