How to pass "args" while using Intellij IDEA [example list 3.11 in Odersky's Scala book (2nd Ed)] - bash

I basically try to run the example 3.11 in Odersky's book (Programming in Scala). I am using Intellij IDE. While runing the code, the "else" branch got executed.
The screen capture is here:
The source is here in case you need it to try:
package ch3
import scala.io.Source
object l3p11 extends App{
def widthOfLength(s: String) = s.length.toString.length
if (args.length > 0){
val lines = Source.fromFile(args(0)).getLines().toList
val longestLine = lines.reduceLeft(
(a, b) => if (a.length > b.length) a else b
)
val maxWidth = widthOfLength(longestLine)
for (line <- lines){
val numSpaces = maxWidth - widthOfLength(line)
val padding = " " * numSpaces
println(padding + line.length + "|" + line)
}
}
else
Console.err.println("Please enter filename")
}
The reason, I think, is becuase I did not pass args correctly (say here I want to pass the source file l3p11.scala as the args). I tried several option, but have not find a way to pass the args correctly for the code to be executed in the "if" branch. There are two directions in my mind to resolve this problem:
1. Find the right way to pass args in Intellij IDE
Run Scala in commond line, a similar command such as
$ scala l3p11.scala l3p11.scala
should be able to pass the args correctly. But my current setting gives "bash: scala: command not found". I currently use scala REPL to run scala code following the set up given in Odersky's Coursera course on Scala. I think I need to change the set up in orde run scala directly, instead of using "sbt->console" to invoke the scala interpreter like what I am doing now.
Any suggestion on either direction (or other directions that I have not thought of) to resolve the problem is welcome.
Update 1:
Direction 2 works after I reinstall scala. (My to be corrected understanding is that the installation of sbt does not provide an executable binary of scala to be included in the environment list for Windows. Therefore, scala command cannot be found before). After installation of scala directly:
$ scala l3p11.scala l3p11.scala
gives the expected results. But I still have not figured out how to get this result with Intellij IDEA.
Update 2:
I revisited the "Program arguments" option after Joe's confirmation. The reason I was not be able to get it work before was that I only add "l3p11.scala". Adding the complete path from working directory "src/main/scala/ch3/l3p11.scala" solved the problem. The result is as following:

To pass command-line arguments when running a program in IntelliJ IDEA, use the "Edit Configurations …" menu item under "Run". Choose the entry for your main program. There's a "Program arguments" text field where you specify the arguments to pass to the program.

I'm not super familiar on how it will run on windows but if you are able to run it directly from the command line then I think you'll need to compile first, that's the scalac command. So:
$ scalac l3p11.scala
then you can run just with the class name, not sure if you would need quotes on the arg:
$ scala l3p11 l3p11.scala

Related

Golang Cobra multiple flags with no value

I'm new to Golang, and i'm trying out my first CLI application, using the Cobra framework.
My plan is to have few commands, with many flags.
These flags, don't have to have a value attached to them, since they can simply be -r to restart the device.
Currently, i have the following working, but i keep thinking, that this cannot be the correct way to do it.
So any help is appreciated.
The logic is currently, that each command, get's a default value attached to it, and then i look for this, in the run command, and triggers my function, once it captures it.
My "working code" looks like below.
My init function, in the command contains the following.
chargerCmd.Flags().StringP("UpdateFirmware", "u", "", "Updeates the firmware of the charger")
chargerCmd.Flags().Lookup("UpdateFirmware").NoOptDefVal = "yes"
chargerCmd.Flags().StringP("reboot", "r", "", "Reboots the charger")
chargerCmd.Flags().Lookup("reboot").NoOptDefVal = "yes"
And the run section looks like this.
Run: func(cmd *cobra.Command, args []string) {
input, _ := cmd.Flags().GetString("UpdateFirmware")
if input == "yes" {
fmt.Println("Updating firmware")
UpdateFirmware(os.Getenv("Test"), os.Getenv("Test2"))
}
input, _ = cmd.Flags().GetString("reboot")
if input == "yes" {
fmt.Println("Rebooting Charger")
}
},
Maybe to make the usage a bit cleaner, as stated in the comment from Burak - you can better differentiate between commands and flags. With cobra you have the root command and sub-commands attached to the root command. Additionaly each command can accept flags.
In your case, charger is the root commands and you want two sub-commands: update_firmware and reboot.
So as an example to reboot the charger, you would execute the command:
$ charger reboot
In the code above, you are trying to define sub-commands as flags, which is possible, but likely not good practice.
Instead, the project should be set-up something like this: https://github.com/hesamchobanlou/stackoverflow/tree/main/74934087
You can then move the UpdateFirmware(...) operation within the respective command definition under cmd/update_firmware.go instead of trying to check each flag variation on the root chargerCmd.
If that does not help, provide some more details on why you think your approach might not be correct?

How to pass command line arguments to Deno?

I have a Deno app, that I wish to pass some command line args to. I searched the manual, but found nothing.
I tried to use the same commands used in Node.js, assuming they might be sharing some for the std libraries, but it didn't work as well.
var args = process.argv.slice(2);
// Uncaught ReferenceError: process is not defined
Any suggestions?
You can access arguments by using Deno.args, it will contain an array of the arguments passed to that script.
// deno run args.js one two three
console.log(Deno.args); // ['one, 'two', 'three']
If you want to parse those arguments you can use std/flags, which will parse the arguments similar to minimist
import { parse } from "https://deno.land/std/flags/mod.ts";
console.log(parse(Deno.args))
If you call it with:
deno run args.js -h 1 -w on
You'll get
{ _: [], h: 1, w: "on" }
You can use Deno.args to access the command line arguments in Deno.
To try it create a file test.ts :
console.log(Deno.args);
And run it with deno run test.ts firstArgument secondArgument
It will return you with an array of the passed args:
$ deno run test.ts firstArgument secondArgument
[ "firstArgument", "secondArgument" ]
If you take a stroll through the standard library, you will find a library named flags, which sounds like it could be library for command line parsing. In the README, you will find your answer in the very first line:
const { args } = Deno;
Also, if you look at the Deno Manual, specifically the Examples section, you will find numerous examples of command line example programs that perform argument parsing, for example, a clone of the Unix cat command (which is also included in the First Steps section of the Deno Manual), where you will also find your answer in the first line:
for (let i = 0; i < Deno.args.length; i++)
So, in short: the command line arguments are a property of the global Deno object, which is documented here:
const Deno.args: string[]
Returns the script arguments to the program. If for example we run a program:
deno run --allow-read https://deno.land/std/examples/cat.ts /etc/passwd
Then Deno.args will contain:
[ "/etc/passwd" ]
Note: According to the Manual, all non-web APIs are under the global Deno namespace.

How can I get $ not escaped in application default jvm args for gradle?

Using the application task I am specifying:
applicationDefaultJvmArgs = ['$DEBUG_OPTS',
'-Djava.library.path=${ZMQ_LIB_PATH}']
In the generated start scripts I see:
DEFAULT_JVM_OPTS='"\$DEBUG_OPTS" "-Djava.library.path=\${ZMQ_LIB_PATH}"'
I don't want the \$ in there. I tried using '$$DEBUG_OPTS' and also '\$DEBUG_OPTS' but got the same result. What is the right way to escape the $ so it ends up in the script without a backslash in front of it?
I had a similar issue, trying to add a commandline parameter $1 in there. With some googling came up with this solution, fixing the script after the fact.
applicationDefaultJvmArgs=['-Dmy.property=DOLLARONE']
...
startScripts{
doLast{
def bashFile = new File(getOutputDir(),applicationName)
String bashContent = bashFile.text
bashFile.text = bashContent.replaceFirst('DOLLARONE', Matcher.quoteReplacement('$1'))
}
}
The StartScriptGenerator code implies that '$' will be unconditionally replaced by the '\$'.
I assume that your intention is to use '$' character for shell parameters extension but I would like to point out that such usage (if permitted by the gradle task that generates the scripts) is not interoperable between bash and bat scripts - in the bash it will be used for shell parameters extension but in the bat it will have no meaning.
For Kotlin build script the solution could look like:
tasks.named<CreateStartScripts>("startScripts") {
doLast {
unixScript.writeText(unixScript.readText().replace("{{APP_HOME}}", "\${APP_HOME}"))
windowsScript.writeText(windowsScript.readText().replace("{{APP_HOME}}", "%APP_HOME%"))
}
}

Haskell Noob In Need of Assistance

This is a bit long, so bear with me!
I'm having a bit of trouble working with a Haskell program, that I have to use as part of a uni project. For reference, it's Casper.
So, you're supposed to execute a script, which is actually a Bash script to invoke Hugs interpreter like this:
exec $HUGSBIN/hugs $HUGSARGS +p"Casper> " $FILES
Where $FILES points to a Main.lhs file.
After this, I need to invoke a function "compile" with a path to a file, in the interpreter.
I need to perform the above in a scripted manner. I need this automated because I'm writing a program that will call on Casper in the background.
So I compiled the .lhs file. Now I want to execute the "compile" function but I have no idea how this is done. I try:
./Main compile <a path>
from the command line but it returns me an error about a file "test" not found. Upon investigation, I see these lines in the Main.lhs file:
>main :: String -> IO()
>main = compile "test"
>compile :: String -> IO()
>compile s = catch (compile0 False s) handler
[...snipped]
The 2nd line solves this question. Now my question is, how do I invoke the "compile" function and pass a path to it after I have compiled main.lhs? From the interpreter, I just type "compile " and it works, but I can't get the same to work after compiling the main.lhs and executing from the command line? Any ideas why? Is there any way I can script Hugs if all else fails?
Thank you for any assistance!
You may access the command-line arguments passed to a Haskell program via getArgs. For example, it sounds like you want a main function that does something like this:
>main = do
> args <- getArgs
> case args of
> [] -> putStrLn "What file did you want me to compile?"
> [filename] -> compile filename
> _ -> putStrLn "I only compile one file at a time."
Modify to taste.
Replace main with
main = getArgs >>= \(arg1:_) -> compile arg1
This will pass the first command line argument (arg1) to compile instead of "test", and ignore the rest (_). You may need to add
import System
or
import System.Environment
I can't remember what is needed in hugs for this.

Uncaught Throw generated by JLink or UseFrontEnd

This example routine generates two Throw::nocatch warning messages in the kernel window. Can they be handled somehow?
The example consists of this code in a file "test.m" created in C:\Temp:
Needs["JLink`"];
$FrontEndLaunchCommand = "Mathematica.exe";
UseFrontEnd[NotebookWrite[CreateDocument[], "Testing"]];
Then these commands pasted and run at the Windows Command Prompt:
PATH = C:\Program Files\Wolfram Research\Mathematica\8.0\;%PATH%
start MathKernel -noprompt -initfile "C:\Temp\test.m"
Addendum
The reason for using UseFrontEnd as opposed to UsingFrontEnd is that an interactive front end may be required to preserve output and messages from notebooks that are usually run interactively. For example, with C:\Temp\test.m modified like so:
Needs["JLink`"];
$FrontEndLaunchCommand="Mathematica.exe";
UseFrontEnd[
nb = NotebookOpen["C:\\Temp\\run.nb"];
SelectionMove[nb, Next, Cell];
SelectionEvaluate[nb];
];
Pause[10];
CloseFrontEnd[];
and a notebook C:\Temp\run.nb created with a single cell containing:
x1 = 0; While[x1 < 1000000,
If[Mod[x1, 100000] == 0,
Print["x1=" <> ToString[x1]]]; x1++];
NotebookSave[EvaluationNotebook[]];
NotebookClose[EvaluationNotebook[]];
this code, launched from a Windows Command Prompt, will run interactively and save its output. This is not possible to achieve using UsingFrontEnd or MathKernel -script "C:\Temp\test.m".
During the initialization, the kernel code is in a mode which prevents aborts.
Throw/Catch are implemented with Abort, therefore they do not work during initialization.
A simple example that shows the problem is to put this in your test.m file:
Catch[Throw[test]];
Similarly, functions like TimeConstrained, MemoryConstrained, Break, the Trace family, Abort and those that depend upon it (like certain data paclets) will have problems like this during initialization.
A possible solution to your problem might be to consider the -script option:
math.exe -script test.m
Also, note that in version 8 there is a documented function called UsingFrontEnd, which does what UseFrontEnd did, but is auto-configured, so this:
Needs["JLink`"];
UsingFrontEnd[NotebookWrite[CreateDocument[], "Testing"]];
should be all you need in your test.m file.
See also: Mathematica Scripts
Addendum
One possible solution to use the -script and UsingFrontEnd is to use the 'run.m script
included below. This does require setting up a 'Test' kernel in the kernel configuration options (basically a clone of the 'Local' kernel settings).
The script includes two utility functions, NotebookEvaluatingQ and NotebookPauseForEvaluation, which help the script to wait for the client notebook to finish evaluating before saving it. The upside of this approach is that all the evaluation control code is in the 'run.m' script, so the client notebook does not need to have a NotebookSave[EvaluationNotebook[]] statement at the end.
NotebookPauseForEvaluation[nb_] := Module[{},While[NotebookEvaluatingQ[nb],Pause[.25]]]
NotebookEvaluatingQ[nb_]:=Module[{},
SelectionMove[nb,All,Notebook];
Or##Map["Evaluating"/.#&,Developer`CellInformation[nb]]
]
UsingFrontEnd[
nb = NotebookOpen["c:\\users\\arnoudb\\run.nb"];
SetOptions[nb,Evaluator->"Test"];
SelectionMove[nb,All,Notebook];
SelectionEvaluate[nb];
NotebookPauseForEvaluation[nb];
NotebookSave[nb];
]
I hope this is useful in some way to you. It could use a few more improvements like resetting the notebook's kernel to its original and closing the notebook after saving it,
but this code should work for this particular purpose.
On a side note, I tried one other approach, using this:
UsingFrontEnd[ NotebookEvaluate[ "c:\\users\\arnoudb\\run.nb", InsertResults->True ] ]
But this is kicking the kernel terminal session into a dialog mode, which seems like a bug
to me (I'll check into this and get this reported if this is a valid issue).

Resources