How do I get args passed to this scala object? - scala

I'm trying to figure out how to pass args to this scala object:
I have this class written in this sbt project path: allaboutscala/src/main/scala/gzip_practice/gzipwriter
package gzip_practice
import java.io._
import java.util.zip._
/** Gzcat
*/
object gzcat extends App {
private val buf = new Array[Byte](1024)
try {
for (path <- args) {
try {
var in = new GZIPInputStream(new FileInputStream(path))
var n = in.read(buf)
while (n >= 0) {
System.out.write(buf, 0, n)
n = in.read(buf)
}
}
catch {
case _:FileNotFoundException =>
System.err.printf("File Not Found: %s", path)
case _:SecurityException =>
System.err.printf("Permission Denied: %s", path)
}
}
}
finally {
System.out.flush
}
}
This is an sbt project called allaboutscala. I am trying to run it with:
scala src/main/scala/gzip_practice/gzipwriter.scala "hi" but the command just hangs and I don't know why.
How am I supposed to run this object constructor with args?

You can use the scala command as a script runner.
Normally, it will wrap your "script" code in a main method.
But if you have an object with a main method, like your App, it will use that for the entry point.
However, it doesn't like package statements in the script.
If you comment out your package statement, you can compile and run with:
scala -nc somefile.scala myarg.gz
-nc means "no compile daemon"; otherwise, it will start a second process to compile scripts, so that subsequent compiles go faster; but it is a brittle workflow and I don't recommend it.
I confirmed that your code works.
Usually, folks use sbt or an IDE to compile and package in a jar to run with scala myapp.jar.

An object is a static instance of a class. You could construct it using:
object gzcat(args: String*) extends App {
...
}
args is bound as a val within the object gzcat.

Are you trying to run it with repl? I would suggest running it with sbt, then you can run sbt projects from project root directory with command line parameter as follows:
sbt "run file1.txt file2.txt"
The quotes are required. If you leave sbt shell open, then it running it will be much faster. Open shell in project root with
sbt
In the sbt shell:
run file1.txt file2.txt
Within the sbt shell, no quotes.

Related

Jflex and CUP not working on vscode and mac

I downloaded jflex by doing brew install jflex everything worked the way it should.
But now when I'm trying to make it work with java_cup.runtime.*. And I keep getting the errors below
Lexer.java:681: error: cannot find symbol
{ return new java_cup.runtime.Symbol(sym.EOF); }
^
symbol: variable sym
location: class Lexer
My proffesor said,
"The Symbol class is
part of the parser (JavaCUP)’s runtime jar file. You may use it in the lexer simply by
setting the classpath to include the jar file from JavaCUP and importing it"
So I made bash file below and did what he said and it is not working.
#!/bin/bash
jflex MiniJava.jflex
javac -cp "/Users/carlosfield/Desktop/School/csc453/java-cup-bin-11b-20160615/java-cup-11b.jar" Lexer.java
java -cp "/Users/carlosfield/Desktop/School/csc453/java-cup-bin-11b-20160615/java-cup-11b-runtime.jar" Lexer Factorial.java
rm Lexer*
This is my jflex file
import java.util.*;
import java_cup.runtime.*;
%%
%class Lexer
%cup
%line
%column
%{
private Symbol symbol(int type) {
return new Symbol(type, yyline, yycolumn);
}
private Symbol symbol(int type, Object value) {
return new Symbol(type, yyline, yycolumn, value);
}
%}
WhiteSpace = [ \t\r\n]
Identifier = [a-zA-Z_][a-zA-Z0-9_]*
Integer = 0 | [1-9][0-9]*
%%
“+” { }
The fix for this issue is that if you use %cup in your jflex file you must then make your own sym class which contains public static final int EOF=0.

IntelliJ breakpoint in scala foreach not working

I'm using IntelliJ IDEA Ultimate 16.1.2 and Scala 12. When setting breakpoints in foreach loops, they don't get hit.
Breakpoints above the foreach work and get the tick in the breakpoint (valid breakpoint) but the ones in the foreach don't get the tick and the program doesn't break there either.
I tried invalidating the IntelliJ Cash, restarting my PC and IntelliJ, rebuilding maven - nothing worked.
This are the VM parameters I'm using, but I've also tried it without any, which didn't help:
-XX:+UnlockCommercialFeatures
-XX:+FlightRecorder
-Dcom.sun.management.jmxremote
-XX:StartFlightRecording=filename=recording.jfr
-server
-Xms1G
-Xmx4G
-XX:+UseG1GC
-XX:+UseStringDeduplication
Thanks for your help!
Here is my code:
class RunTestCasesAction extends AbstractAction {
def actionPerformed(e: ActionEvent) = {
val parent = methodToGetParentComponent() //breakpoint works
getFileName(parent).foreach { testFileName =>
val dialog = new SomeDialog() // breakpoint doesn't work
}
}
private def getFileName(parent: Component): Option[String] = {
val baseDir = getExportDir
val fc = new JFileChooser(baseDir)
val rc = fc.showDialog(null, "Select test file")
if (rc == JFileChooser.APPROVE_OPTION) Some(fc.getSelectedFile.toString) else None
}
What you are doing is creating new objects and assigning them inside a foreach loop.
This has no effect on other part on the projects.
Compiler optimizes your code and this way this code block is never executed. This val dialog = new SomeDialog() are created inside foreach and this objects are immediatelly destroyed, cause their scope is only inside foreach loop, so there is no point of doing it so.
If you want to go inside the loop, put there something what matters, what will be reusable. Eg. you can collect this objects.
Make sure compiler will not optimize your code this way.
Probably you could try to use some compiler optimizations flags, but I am not sure about that.
Here are informations on how debuggers work.

Couldn't run individual scala test in Intellij

I came across an issue earlier where I couldn't run an indivdual scala test, it would always try to run all of them even if I set the configuration to just be running one test. Does anyone know of any settings/configuration I can change to get it to run?
class MyTest extends PlaySpec {
val setTo = new AfterWord("set to")
"Setting" when setTo {
"value a" in {
//test stuff
}
"value b" in {
//test stuff
}
}
Turns out it was the use of the AfterWord that was messing up my test, once I removed it the tests ran fine. I'm not sure why they're incompatible but if you want to run individual tests, don't use an AfterWord.

SBT Command that Calls Another Command and an InputTask

I am writing an SBT Command that is supposed to call another command (eclipse from the Eclipse SBT Plugin) and another InputTask.
How can one achieve this?
Assuming that you want to create a "release" command and it needs to call another task named "pack", you can add the following code to build.sbt:
commands += Command.command("release")((state:State) => {
Project.evaluateTask(pack, state)
println("release called")
state
})
Updated:
In addition, if you have to create the "release" command and it requires calling another command named "init_compile", then the following sample code can be used:
commands += Command.command("init_compile")((state:State) => {
println("init_compile called.")
state
})
commands += Command.command("release")((state:State) => {
val newState = Command.process("init_compile",state)
println("release called.")
newState
})

Handling program args with Groovy Eclipse plugin v2

I am wondering how to handle program arguments when you are running Groovy within Eclipse. It isn't as straight forward as it is from the command line and I am having trouble figure it out. Im using Eclipse 3.5. My run configuration has these arguments all on one line:
--classpath "${workspace_loc:/GroovyProject};${workspace_loc:/GroovyProject}"
--main groovy.ui.GroovyMain "C:\Temp\Workspace\GroovyProject\GroovyTest.groovy "
argtest1
argtest2
argtest3
The script I am using to try to make this work looks like this:
// GroovyTest.groovy
class GroovyTest {
static main(args) {
println "hello, world"
for (arg in this.args ) {
println "Argument:" + arg;
}
}
}
The error I get is:
hello, world
Caught: groovy.lang.MissingPropertyException: No such property: args
for class: GroovyTest at GroovyTest.main(GroovyTest.groovy:5)
You have az unnecessary this in the for (arg in this.args) line.
this.args means that you have an instance of the GroovyTest object and you refer to its args field. In this case args is a method parameter so you have to refer to it simply as args.