I can't use scalax because it is in a state between sbt 0.7.7 and sbt 0.11.2 and will not install on windows. (it is missing org.scala-tools.sbt#sbt_2.7.7;0.4.7-p10 even though I have downloaded that and changes scripts to match - newbie well out of his depth).
I can find no examples in the web without scalax.
All I want to do is write some lines of text to a file. However I don't want to have all lines in memory at once.
Can someone point me at an example?
Scala 2.9, Windows 7 - 64 bit.
The easiest thing to do would probably be using java.io.PrintWriter like so:
scala> val pw = new java.io.PrintWriter("/tmp/foo.txt")
pw: java.io.PrintWriter = java.io.PrintWriter#1e1ff563
scala> pw.println("Hello")
scala> pw.close()
You might want to look up PrintWriter here.
Related
I'm using Breeze to to do sum simple linear algebra operations on dense matrices. I'm using the Intellij IDEA. Here is an snippet of my code:
import breeze.linalg._
val X1:DenseMatrix[Double] = DenseMatrix.zeros[Double](10, 5) + 1.0
val n1 : Double = X1.rows.toDouble
val one_tall_t1 = DenseMatrix.zeros[Double](1, n1.toInt) + 1.0
val mu1=one_tall_t1*X1/n1
In the last line, the symbols * and / are shown with red color in the IDE. The error message is "Cannot resolve the symbol *".
But Intellij builds the program without any errors, and it runs fine.
I've been trying to find out the reason: since I'm new to Scala, I'm not sure if it is because of Intellij, Breeze, or just my code. In some posts, people have suggested to invalidate cache and restart Intellij, but this does not solve my issue.
I appreciate your comments or solutions!
IntelliJ gets confused by complex implicit searches like those used in Breeze. I file bugs when I can minimize them and get around to it, but it's a slog. (Eclipse, for what it's worth, isn't much better.)
It typically works better if you're just depending on Breeze, not developing inside of it. I assume you're doing that already though.
In my quest to generate new code in a Scala compiler plugin, I have now created working classes. The next logical step is to put those classes in a new, non-existing package. In Java, a package is basically a directory name, but in Scala a package seems much more complicated. So far I haven't found/recognized an example where a compiler plugin creates a new package.
At my current level of understanding, I would think that I would need to create first a package symbol with:
parentPackage.newPackage(...)
// ...
and than later create a Tree for the package with PackageDef. But PackageDef doesn't take the symbol as parameter, as one would expect, and searching for:
Scala newPackage PackageDef
returned nothing useful. So it seems that I don't need to do those two steps together. Possibly one is done for my by the compiler, but I don't know which one. So far, what I have looks like this:
val newPkg = parentPackage.newPackage(NoPosition, newTermName(name))
newPkg.moduleClass.setInfo(new PackageClassInfoType(new Scope,
newPkg.moduleClass))
newPkg.setInfo(newPkg.moduleClass.tpe)
parentPackage.info.decls.enter(newPkg)
// ...
val newPkgTree = PackageDef(Ident(newPkg.name), List(ClassDef(...)))
I think my answer to your other question should answer this one as well:
How to add a new Class in a Scala Compiler Plugin?
This question already has answers here:
How do I get the Scala version from within Scala itself?
(4 answers)
Closed 1 year ago.
When trying to run some code in online interpreters or with IRC bots, I always wonder which version of Scala they support.
Is there a way to retrieve the version of Scala from within the interpreter?
For Scala 2, use scala.util.Properties.versionNumberString (or versionString):
scala> scala.util.Properties.versionString
val res0: String = version 2.13.6
scala> scala.util.Properties.versionNumberString
val res1: String = 2.13.6
For Scala 3, if you do the same thing, you may be surprised by the answer:
% scala3 -version
Scala code runner version 3.0.1 -- Copyright 2002-2021, LAMP/EPFL
% scala3
scala> scala.util.Properties.versionNumberString
val res0: String = 2.13.6
That's because Scala 3.0.x uses the Scala 2 standard library as-is, to aid migration, and makes only a small number of additions. (Eventually the standard libraries will no longer remain synchronized like this.)
Here's how to get the Scala 3 compiler version:
scala> dotty.tools.dotc.config.Properties.simpleVersionString
val res0: String = 3.0.1
This only works if the scala3-compiler JAR is on your classpath. (In the standard Scala 3 REPL, it is; in some other environments, it might not be.)
If the compiler isn't on your classpath and you want the full Scala 3 version string, see Dmitrii's answer.
If the compiler isn't on your classpath but you just want to find out at runtime whether you're on Scala 2 or 3, well... perhaps there's a cleaner/better way, you tell me, but one way that works is:
util.Try(Class.forName("scala.CanEqual")).isSuccess
Here, the choice of scala.CanEqual is arbitrary, it could be any of the small number of classes that are in scala3-library but not scala-library.
But if you are tempted to go that route, you might instead consider including version-specific source in your project, or passing the Scala version via sbt-buildinfo.
scala> scala.util.Properties.versionMsg
res: String = Scala library version 2.9.0.1 -- Copyright 2002-2011, LAMP/EPFL
Looks of course like the library version and not like the language version, but I think currently there won’t be a real difference in practice.
If you need just the version number without the "version" keyword you can use versionNumberString function.
scala> scala.util.Properties.versionNumberString
res1: String = 2.12.3
If you want to get the exact Scala 3 version, you can read it from the Manifest file
.../scala3-library_3-3.0.1.jar!/META-INF/MANIFEST.MF
import java.io.FileInputStream
import java.util.jar.JarInputStream
val scala3LibJar = classOf[CanEqual[_, _]].getProtectionDomain.getCodeSource.getLocation.toURI.getPath
val manifest = new JarInputStream(new FileInputStream(scala3LibJar)).getManifest
manifest.getMainAttributes.getValue("Implementation-Version")
Example in Scastie:
Someday, I'd like to learn Scala. What I see about the language from people who like it is very encouraging.
Today, though, is not that day. Today, I'd just like to make some changes to my team's build file. Unfortunately, this build file was put together with SBT, and is nearly incomprehensible.
My main issue is that it appears to me that SBT introduces some huge collection of new operators that do things with strings and lists to create some sort of sbt object. For example, in sbt:
"args4j" % "args4j" % "2.0.12"
Apparently is actually defined; however, I can't even tell what type it is at the scala repl, since at the repl I get the sensible error:
scala> val tstcrap = "args4j" % "args4j" % "2.0.12"
<console>:6: error: value % is not a member of java.lang.String
val tstcrap = "args4j" % "args4j" % "2.0.12"
I get this error even after setting up the classpath to include the sbt-launch.jar file and doing import sbt._.
Likewise, I'm dealing with stuff like this:
val jarSources = (descendents(classesOutput ##, "*") ---
assemblyExclude(classesOutput ##))
What's that ## operator, what's that --- doing, and more importantly what is the type of this expression? Are all these new operators documented somewhere, and is there some way to get a scala repl that's using the same language as is used in the sbt build files?
Looking at this sbt file reminds me of trying to decipher perl without ever reading any of the relevant man pages. (Not a recommended activity)
Update: After looking at the links in the answer below, and looking at other questions and answers tagged sbt, I've come across the major piece of scala knowledge that I was missing: scala allows one to define implicit conversions that will be invoked before methods are resolved. In this case, sbt defines inside the ManagedProject trait, an implicit conversion from String to the private class sbt.GroupID, so that
"a" % "b"
Is really something like
(new GroupID("a")) % "b"
I imagine the resolution order and other rules around implicit conversions must get very complicated; it almost reminds me of the nightmares you can introduce in C++ with operator overloading when done through non-member functions.
Since an SBT build file is a full-fledged Scala source file and relies on some libraries provided by SBT itself, it's difficult to cover SBT well without relying on some familiarity with Scala. I'm not aware of such a guide.
For the specific questions you raise, I think these wiki pages will help:
% operator for strings: http://code.google.com/p/simple-build-tool/wiki/LibraryManagement
## and --- operators: http://code.google.com/p/simple-build-tool/wiki/Paths
If you want to get a Scala REPL running with the SBT libraries available, try this:
$ sbt console-project
Some other useful commands are listed at http://code.google.com/p/simple-build-tool/wiki/RunningSbt .
Update 2016 (5 years later).
This is not a complete guide, but the article "Sbt heiroglyphs and multi-projects explained" from Divan Visagie can help starting to use sbt.
Plus, the sbt documentation is quite complete nowadays, and covers multiple projects in a single build.
The '---' operator is described in the PathFinder (since the 0.2 version).
I almost always have a Scala REPL session or two open, which makes it very easy to give Java or Scala classes a quick test. But if I change a class and recompile it, the REPL continues with the old one loaded. Is there a way to get it to reload the class, rather than having to restart the REPL?
Just to give a concrete example, suppose we have the file Test.scala:
object Test { def hello = "Hello World" }
We compile it and start the REPL:
~/pkg/scala-2.8.0.Beta1-prerelease$ bin/scala
Welcome to Scala version 2.8.0.Beta1-prerelease
(Java HotSpot(TM) Server VM, Java 1.6.0_16).
Type in expressions to have them evaluated.
Type :help for more information.
scala> Test.hello
res0: java.lang.String = Hello World
Then we change the source file to
object Test {
def hello = "Hello World"
def goodbye = "Goodbye, Cruel World"
}
but we can't use it:
scala> Test.goodbye
<console>:5: error: value goodbye is not a member of object Test
Test.goodbye
^
scala> import Test;
<console>:1: error: '.' expected but ';' found.
import Test;
There is an alternative to reloading the class if the goal is to not have to repeat previous commands. The REPL has the command
:replay
which restarts the REPL environment and plays back all previous valid commands. (The invalid ones are skipped, so if it was wrong before, it won't suddenly work.) When the REPL is reset, it does reload classes, so new commands can use the contents of recompiled classes (in fact, the old commands will also use those recompiled classes).
This is not a general solution, but is a useful shortcut to extend an individual session with re-computable state.
Note: this applies to the bare Scala REPL. If you run it from SBT or some other environment, it may or may not work depending on how SBT or the other environment packages up classes--if you don't update what is on the actual classpath being used, of course it won't work!
Class reloading is not an easy problem. In fact, it's something that the JVM makes very difficult. You do have a couple options though:
Start the Scala REPL in debug mode. The JVM debugger has some built-in reloading which works on the method level. It won't help you with the case you gave, but it would handle something simple like changing a method implementation.
Use JRebel (http://www.zeroturnaround.com/jrebel). JRebel is basically a super-charged class reloading solution for the
JVM. It can handle
member addition/removal, new/removed classes, definition changes, etc. Just about the only thing it can't handle is changes in class hierarchy (adding a super-interface, for
example). It's not a free tool, but they do offer a complementary license which is limited to Scala compilation units.
Unfortunately, both of these are limited by the Scala REPL's implementation details. I use JRebel, and it usually does the trick, but there are still cases where the REPL will not reflect the reloaded class(es). Still, it's better than nothing.
There is an command meet you requirement
:load path/to/file.scala
which will reload the scala source file and recompiled to classes , then you can replay you code
This works for me....
If your new source file Test.scala looks something like this...
package com.tests
object Test {
def hello = "Hello World"
def goodbye = "Goodbye, Cruel World"
}
You first have to load the new changes into Scala console (REPL).
:load src/main/scala/com/tests/examples/Test.scala
Then re-import the package so you can reference the new code in Scala console.
import com.tests.Test
Now enjoy your new code without restarting your session :)
scala> Test.goodbye
res0: String = Goodbye, Cruel World
If the .scala file is in the directory where you start the REPL you can ommit the full path, just put :load myfile.scala, and then import.