I am trying to learn scala. In the Squeryl documentation I have come across this sign ++=. What does this sign mean? The code was -
libraryDependencies ++= Seq(
"org.squeryl" %% "squeryl" % "0.9.5-6",
yourDatabaseDependency
)
This is simply a method that appends a Seq of dependencies to the libraryDependencies setting. As compared to +=, which appends a single dependency (opposed to a Seq).
For more info, you might want to check out the sbt docs
This isn't part of Scala itself; it's a method in SBT.
libraryKeys is a SettingKey[Seq[ModuleID]], so take a glance at the API doc for SettingKey.
++= is one of the methods on SettingKey. Its return type is Setting.
As a general convention in Scala collections, ++= method takes a collection (right hand side) and puts it into "this" collection (left hand side). SBT uses collections for dependency lists and they are no exception.
Related
From my understanding I should be able to use the banana-rdf library in my scalajs code? I followed the instructions on the website and added the following to my build.sbt:
val banana = (name: String) => "org.w3" %% name % "0.8.4" excludeAll (ExclusionRule(organization = "org.scala-stm"))
and added the following to my common settings:
resolvers += "bblfish-snapshots" at "http://bblfish.net/work/repo/releases"
libraryDependencies ++= Seq("banana", "banana-rdf", "banana-sesame").map(banana)
It all compiles fine until it gets to the point where it does the fast optimizing. Then I get the following error:
Referring to non-existent class org.w3.banana.sesame.Sesame$
I tried changing Seasame for Plantain but got the same outcome.
Am I missing something?
I was using the "%%" notation which is for a jvm module.
Changed it to "%%%" and it was able to find the correct library.
NOTE. I had to use Plantain as this is the only one currently compiled for scalajs
I'm trying to run a basic app from the following example:
https://github.com/confluentinc/examples/blob/3.3.x/kafka-streams/src/main/scala/io/confluent/examples/streams/MapFunctionScalaExample.scala
However I'm getting an exception at this line:
// Variant 1: using `mapValues`
val uppercasedWithMapValues: KStream[Array[Byte], String] = textLines.mapValues(_.toUpperCase())
Error:(33, 25) missing parameter type for expanded function ((x$1) =>
x$1.toUpperCase())
textLines.mapValues(_.toUpperCase())
Error I'm getting if I hover cursor over the code:
Type mismatch, expected: ValueMapper[_ >: String, _ <: NotInferedVR],
actual: (Any) => Any Cannot resolve symbol toUpperCase
Contents of my sbt file:
name := "untitled1"
version := "0.1"
scalaVersion := "2.11.11"
// https://mvnrepository.com/artifact/org.apache.kafka/kafka_2.11
libraryDependencies += "org.apache.kafka" % "kafka_2.11" % "0.11.0.0"
// https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients
libraryDependencies += "org.apache.kafka" % "kafka-clients" % "0.11.0.0"
// https://mvnrepository.com/artifact/org.apache.kafka/kafka-streams
libraryDependencies += "org.apache.kafka" % "kafka-streams" % "0.11.0.0"
// https://mvnrepository.com/artifact/org.apache.kafka/connect-api
libraryDependencies += "org.apache.kafka" % "connect-api" % "0.11.0.0"
I'm really not sure how to proceed with that as I'm quite new to Scala. I'd like to know what's the issue and how to fix it.
From http://docs.confluent.io/current/streams/faq.html#scala-compile-error-no-type-parameter-java-defined-trait-is-invariant-in-type-t
The root cause of this problem is Scala-Java interoperability – the Kafka Streams API is implemented in Java, but your application is written in Scala. Notably, this problem is caused by how the type systems of Java and Scala interact. Generic wildcards in Java, for example, are often causing such Scala issues.
To fix the problem you would need to declare types explicitly in your Scala application in order for the code to compile. For example, you may need to break a single statement that chains multiple DSL operations into multiple statements, where each statement explicitly declares the respective return types. The StreamToTableJoinScalaIntegrationTest demonstrates how the types of return variables are explicitly declared.
Update
Kafka 2.0 (will be released in June) contains a proper Scala API that avoid those issues. Compare https://cwiki.apache.org/confluence/display/KAFKA/KIP-270+-+A+Scala+Wrapper+Library+for+Kafka+Streams
I have a multi-project SBT build. There is a root which does not have anything, it just aggregates all sub projects.
lazy val aaRoot = (project in file(".")).settings(commonSettings: _*).settings(
libraryDependencies ++= appDependencies
).enablePlugins(PlayJava).aggregate(foo, bar)
lazy val foo: Project = (project in file("modules/foo")).settings(commonSettings: _*).settings(
libraryDependencies ++= appDependencies
).enablePlugins(PlayJava).dependsOn(bar)
lazy val bar = (project in file("modules/bar")).settings(commonSettings: _*).settings(
libraryDependencies ++= appDependencies
).enablePlugins(PlayJava).dependsOn(foo)
It is clearly a cyclic dependency here (foo depends on bar and bar depends on foo). What are the possible approaches to avoid these kinds of dependencies or is there an SBT way of handling this.
None of the build tools I know allow for cyclic dependencies... and in my experience that is a symptom of a issue with the design of the application or modules, rather than a 'missing' feature from the tools. It's even seen as something bad when this happens at the package level in the same module/jar.
Can you merge those 2 modules? or reshufle the classes so the cyclic dependency disappears?
As #Augusto suggested, I have re-organized my classes into three different sub-modules and using my Dependency Injection little more wisely. This solved my problem and gave much more abstraction than what I initially had.
Three sub-projects:
api (Just interfaces)
foo (depends on api)
bar (depends on api)
aaRoot (which aggregates all of the above)
In FooModule (in my case Guice module), I am binding FooInterface from api module to FooImplementation (foo module). While calling the bar module, I just use BarInterface (from api) by passing FooInterface.
Same as the case with bar module.
At runtime they all will be available and it can easily resolve.
If I want to generate compile time error when calling .get on any Option value, how to go about doing this?
Haven't written any custom macros but guess it's about time for it? Any pointers?
There is a compiler plugin called wartremover, that provides what you want.
https://github.com/typelevel/wartremover
It has error messages and warning for some scala functions, that should be avoided for safety.
This is the description of the OptionPartial wart from the github readme page:
scala.Option has a get method which will throw if the value is
None. The program should be refactored to use scala.Option#fold to
explicitly handle both the Some and None cases.
compiler plugin
To add wartremover, as a plugin, to scalac, you need to add this to your project/plugins.sbt:
resolvers += Resolver.sonatypeRepo("releases")
addSbtPlugin("org.brianmckenna" % "sbt-wartremover" % "0.11")
And activate it in your build.sbt:
wartremoverErrors ++= Warts.unsafe
macro
https://github.com/typelevel/wartremover/blob/master/OTHER-WAYS.md descripes other ways how you can use the plugin, one of them is using it as a macro, as mentioned in the question.
Add wart remover as library to your build.sbt:
resolvers += Resolver.sonatypeRepo("releases")
libraryDependencies += "org.brianmckenna" %% "wartremover" % "0.11"
You can make any wart into a macro, like so:
scala> import language.experimental.macros
import language.experimental.macros
scala> import org.brianmckenna.wartremover.warts.Unsafe
import org.brianmckenna.wartremover.warts.Unsafe
scala> def safe(expr: Any):Any = macro Unsafe.asMacro
safe: (expr: Any)Any
scala> safe { 1.some.get }
<console>:10: error: Option#get is disabled - use Option#fold instead
safe { 1.some.get }
The example is adapted from the wartremover github page.
Not strictly an answer to your question, but you might prefer to use Scalaz's Maybe type, which avoids this problem by not having a .get method.
Question says it all.
(Yet, the details of how to get access to the shift and reset operations has changed over the years. Old blog entries and Stack Overflow answers may have out of date information.)
See also What are Scala continuations and why use them? which talks about what you might want to do with shift and reset once you have them.
Scala 2.11
The easiest way is to use sbt:
scalaVersion := "2.11.6"
autoCompilerPlugins := true
addCompilerPlugin(
"org.scala-lang.plugins" % "scala-continuations-plugin_2.11.6" % "1.0.2")
libraryDependencies +=
"org.scala-lang.plugins" %% "scala-continuations-library" % "1.0.2"
scalacOptions += "-P:continuations:enable"
In your code (or the REPL), do import scala.util.continuations._
You can now use shift and reset to your heart's content.
historical information for Scala 2.8, 2.9, 2.10
You have to start scala (or scalac) with the -P:continuations:enable flag.
In your code, do import scala.util.continuations._
You can now use shift and reset to your heart's content.
If you're using sbt 0.7, see https://groups.google.com/forum/#!topic/simple-build-tool/Uj-7zl9n3f4
If you're using sbt 0.11+, see https://gist.github.com/1302944
If you're using maven, see http://scala-programming-language.1934581.n4.nabble.com/scala-using-continuations-plugin-with-2-8-0-RC1-and-maven-td2065949.html#a2065949
Non SBT solution:
scala -Xpluginsdir /.../scala/lib/ -P:continuations:enable
Works on scala 2.11.6, but the plugin/library said that it will no longer be included with Scala 2.12