Given a text file, "hello.jl" in the current directory:
" Example hello world program."
function hello()
println("hello, world")
end
how would you display this to the Julia 1.0.0 REPL?
This is what I have so far:
julia> disp(f) = for line in readlines(open(f)); println(line); end
disp (generic function with 1 method)
julia> disp("hello.jl")
" Example hello world program."
function hello()
println("hello, world")
end
Is there a built-in command to do this in Julia?
You can use the run function and pass it a Cmd argument, in Linux, to run the cat system command.
Type semicolon ; in order to change to shell mode:
shell> cat hello.jl
"Example hello world program."
function hello()
println("hello, world")
end
Use the run function to execute a command outside of Julia:
julia> run(`cat hello.jl`) # Only works on Unix like systems.
"Example hello world program."
function hello()
println("hello, world")
end
Process(`cat hello.jl`, ProcessExited(0))
In Windows the type command should be analogous to Unix cat:
julia> show_file(path::AbstractString) = run(#static Sys.isunix() ? `cat $path` : `type $path`)
show_file (generic function with 1 method)
run returns the Process object:
julia> show_file("hello.jl")
"Example hello world program."
function hello()
println("hello, world")
end
Process(`cat hello.jl`, ProcessExited(0))
Use semicolon ; at the end of the line, to suppress the return output in the REPL:
julia> show_file("hello.jl");
"Example hello world program."
function hello()
println("hello, world")
end
Or you could just return nothing at the end of show_file if you like.
In the julia REPL, hit
;
to get to the REPL's built-in shell mode, then
shell> head path/to/my/filename
println(String(read("hello.jl")))
or
"hello.jl" |> read |> String |> println
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
I have been working through Harvard's CS51 class using materials available online. I'm trying to start the final project and downloaded the necessary files, but when I try to compile them I get the following error:
Error: Module `Unix' is unavailable (required by `Thread')
Command exited with code 2.
Compilation unsuccessful after building 18 targets (15 cached) in 00:00:00.
I have not made any changes to the code I downloaded yet and supposedly I should be able to compile it successfully in its current state. Any ideas why I might be getting this error?
EDIT: Below is the code from the file I downloaded and am trying to compile.
module Ev = Evaluation ;;
module MP = Miniml_parse ;;
module ML = Miniml_lex ;;
module Ex = Expr ;;
open Printf ;;
(* str_to_exp str -- Returns the expression specified by `str` using
the MiniML parser. *)
let str_to_exp (str: string) : Ex.expr =
let lexbuf = Lexing.from_string str in
let exp = MP.input ML.token lexbuf in
exp ;;
(* repl () -- Read-eval-print loop for MiniML, which prompts for and
evaluates MiniML expressions, printing the resulting value. Exits
the loop and terminates upon reading an end-of-file
(control-d). *)
let repl () =
(* lexical analyzer buffer from stdin *)
let lexbuf = Lexing.from_channel stdin in
(* set up the initial environment *)
let env = Ev.Env.empty () in
(* the main LOOP *)
while true do
(try
(* prompt *)
printf "<== %!";
(* READ and parse an expression from the input *)
let exp = MP.input ML.token lexbuf in
(* EVALuate it *)
let res = Ev.evaluate exp env in
(* PRINT the result; in this initial version, the trivial
evaluator just returns the expression unchanged as an
element of the `Env.value` type (found in `expr.ml`), so we
just extract the expression back out and print it *)
match res with
| Val resexp ->
printf "==> %s\n" (Ex.exp_to_abstract_string resexp)
| _ -> failwith "not handling other cases yet"
with
| MP.Error -> printf "xx> parse error\n"
| Ev.EvalError msg -> printf "xx> evaluation error: %s\n" msg
| Ev.EvalException -> printf "xx> evaluation exception\n"
| End_of_file -> printf "Goodbye.\n"; exit 0
);
flush stdout
done
;;
(* Run REPL if called from command line *)
try
let _ = Str.search_forward (Str.regexp "miniml\\.\\(byte\\|native\\|bc\\|exe\\)")
(Sys.argv.(0)) 0 in
repl ()
with Not_found -> () ;;
If I add open Unix it does take care of the error above, but I then get a different error:
26 | let lexbuf = Lexing.from_channel stdin in
^^^^^
Error: This expression has type Unix.file_descr
but an expression was expected of type in_channel
Command exited with code 2.
Generally, you have to explicitly ask to be linked to the Unix module.
The following program:
$ cat main.ml
Unix.gethostname () |> print_endline
would need to be built like this:
$ ocamlfind opt -linkpkg -package unix -o main main.ml; echo $?
0
whereas the bare minimum would fail with a similar error as yours:
$ ocamlopt -o main main.ml; echo $?
File "main.ml", line 1:
Error: No implementations provided for the following modules:
Unix referenced from main.cmx
2
That said, it looks like you're using Core, in which case (as well as most
other cases, actually) you're probably better off with dune:
$ cat dune
(executable
(name main)
(libraries unix))
$ dune build main.exe
$ ./_build/default/main.exe
amam-oy
However, if you ask Dune to link you to Core, Unix is already included
automatically, so the following dune file would also work for the above
program:
$ cat dune
(executable
(name main)
(libraries core))
Just add
open Unix;;
at the very start of your .ml file
I want to write a program that watches a .dll for changes. When a change happens, it should load the assembly and invoke the foo function inside.
I have some code that should implement this, but it behaves strangely. Sometimes it works. Sometimes the assembly it loads will be an old version. Sometimes it will throw a BadImageFormatException exception.
Here is my program code (it is F# but I think this is a general .NET Core question):
module HotReloadDemo
open System
open System.IO
open System.Reflection
[<EntryPoint>]
let main argv =
let assemblyPath = argv.[0] // Path to the .dll to watch
let mutable lastWriteTime = DateTime.MinValue
while true do
let writeTime =
if File.Exists assemblyPath
then
File.GetLastWriteTimeUtc assemblyPath
else
lastWriteTime
if writeTime > lastWriteTime
then
lastWriteTime <- writeTime
try
printfn "Last write time: %O " lastWriteTime
printfn "Waiting for the build to finish (this is a hack)... "
Threading.Thread.Sleep 10000 // 10s is plenty long enough for the build to finish
printfn "Loading assembly path from: %s " assemblyPath
let assembly = Assembly.LoadFrom assemblyPath
printfn "Got assembly: %O" (assembly.GetName ())
let foo : (Unit -> int) option =
assembly.GetExportedTypes()
|> Array.tryHead
|> Option.bind (fun t -> t.GetMethod "foo" |> Option.ofObj)
|> Option.map (fun m -> (fun () -> m.Invoke (null, Array.empty) :?> int))
match foo with
| Some foo ->
printfn "foo () = %O" (foo ())
| None ->
printfn "foo not found"
with exn ->
printfn "%O" exn
else
()
Threading.Thread.Sleep 1000
0
I then have a very simple library to be watched in another project like this:
module HotReload
let foo () =
123456
To test it, I launch the "watcher" program. It successfully loads and invokes foo.
Then, I modify my library (e.g. to return a different number) and build it with dotnet build.
The watcher detects the change, loads the assembly again and invokes foo, but it prints the number from before the change!
Then, I modify the library again with a different number. It detects the change but crashes:
...
Loading assembly path from: ../hot-reload-lib/bin/Debug/netstandard2.0/hot-reload-lib.dll
System.BadImageFormatException: Could not load file or assembly '<Unknown>'. Index not found. (0x80131124)
File name: '<Unknown>'
at System.Runtime.Loader.AssemblyLoadContext.LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, String ilPath, String niPath, ObjectHandleOnStack retAssembly)
at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)
...
What is going on here?
dotnet --version
3.0.100
lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.3 LTS
Release: 18.04
Codename: bionic
I am trying to run some autoit.au3 script from command line and see results there. I have put some ConsoleWrite inside script and also Exit(1) but after I run script nothing is shown in console. It just stop script on Exit and ConsoleWrite is not displayed.
I have use command:
"C:...(path to my AutoIt3.exe)" /ErrorStdOut "path_to_my_script.au3"'
Also I have tried to run script.exe with this same command but with similar (no) result. I would like to see output in console and/or custom error messages when script fail (I don't know if that is possible).
AutoIt3.exe is a GUI program. So the STD streams of a GUI program are not printed at a console by default.
The /ErrorStdOut argument redirects errors messages to Console instead of a Msgbox.
This argument does not enable print at the Console.
Command Prompt:
To print at a Command Prompt, you could pipe to more, i.e.
"C:...(path to my AutoIt3.exe)" /ErrorStdOut "path_to_my_script.au3" 2>&1|more
more reads from the Stdin stream and prints to Console.
I intentionly added 2>&1 so the Stderr stream is merged with
Stdout so you get the merged streams printed.
If you do not want the errors, then you can redirect the Stderr stream to nul i.e.
replace 2>&1 with 2>nul.
If you used a for loop at a Command Prompt, it would be i.e.
for /f "delims=" %A in ('"C:...(path to my AutoIt3.exe)" /ErrorStdOut test1.au3') do echo %A
If you use the for loop in batch-file, use %%A instead of %A. To also capture the Stderr, insert 2^>&1 into the for command or to ignore, insert 2^>nulinto the for command i.e.
for /f "delims=" %A in ('2^>nul "C:...(path to my AutoIt3.exe)" /ErrorStdOut test1.au3') do echo %A
The previous methods will not get the Exitcode.
AutoIt code:
An AutoIt script can get the Stdout and the Exitcode.
#pragma compile(Out, 'consoleau3.exe')
#pragma compile(Console, True)
$sAutoit = 'C:...(path to my AutoIt3.exe)'
$iPid = Run('"' & $sAutoit & '" /ErrorStdout ' & $CMDLINERAW, '', #SW_SHOW, 2) ; 2 = Get Stdout stream.
If #error Then Exit
; Open process handle.
$hPid = _ProcessOpenHandle($iPid)
; Get Stdout stream and then print to Console.
$sStdout = ''
Do
Sleep(10)
If $sStdout Then ConsoleWrite($sStdout & #CRLF)
$sStdout = StdoutRead($iPid)
Until #error
; Require process to be closed before calling _ProcessGetExitCode()
ProcessWaitClose($iPid)
; Get exitcode of process.
$iExitcode = _ProcessGetExitCode($hPid)
; Close process handle.
_ProcessCloseHandle($hPid)
Exit $iExitcode
Func _ProcessOpenHandle($iPID)
; Get the process handle of the process to query\n Return: Success Handle as array. Failure 0
Local Const $PROCESS_QUERY_INFORMATION = 0x400
Local $hPID = DllCall('kernel32.dll', 'ptr', 'OpenProcess', 'int', $PROCESS_QUERY_INFORMATION, 'int', 0, 'int', $iPID)
If #error Then Return SetError(#error, #extended, 0)
Return $hPID[0]
EndFunc
Func _ProcessGetExitcode($hPID)
; Get exitcode of the closed process\n Return: Success Exitcode as integer. Failure 0
Local $vPlaceholder
$hPID = DllCall('kernel32.dll', 'ptr', 'GetExitCodeProcess', 'ptr', $hPID, 'int*', $vPlaceholder)
If #error Then Return SetError(#error, #extended, 0)
Return $hPID[2]
EndFunc
Func _ProcessCloseHandle($hPID)
; Close the handle of a process\n Return: Success 1. Failure 0
DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $hPID)
If #error Then Return SetError(#error, #extended, 0)
Return 1
EndFunc
Correct the path to AutoIt.exe in the code.
Compile to AutoIt code to executable. It will be a Console program
and will be named consoleau3.exe as to the #pragma compile directives.
Usage:
consoleau3 "path_to_my_script.au3"
Script arguments can be added i.e.
consoleau3 "path_to_my_script.au3" arg1 arg2 arg3 ...
I want to capture all output from R console. I tried to use sink() function and txtStart() of library 'TeachingDemos'. However, none of them can capture the output from system() command.
For example
If I run the below codes:
zz <- file("log.txt")
sink(zz)
sink(zz, type = "message")
print('first layer message!!!!')
system("Rscript test1.R") #test1.R is a R script that print 'hello world'
sink(type = "message")
sink()
I can see the message 'hello world' in the R console. However, I cannot write it into log.txt. Is there any way to solve this?
Thanks
system("Rscript test1.R", intern = TRUE)
In julia, how do I check if the current is allowed to write to a folder?
I could do the python way, and just attempt to do it, and then fail fail and recover.
(In my case I can definitely recover, I have a list of locations to attempt to write to, as fallbacks. I expect the first few not to work (The first few are shared locations, so only computer admins are likely to have permission to writer there)
Python has also os.access function. Maybe Julia will have something similar in the future. Now we could borrow idea. :)
It is implemented in posixmodule.c (also functionality for windows!) so if you are on posix you could simply mimic:
julia> const R_OK = 4 # readability
julia> const W_OK = 2 # writability
julia> const X_OK = 1 # executability
julia> const F_OK = 4 # existence
julia> access(path, mode) = ccall(:access, Cint, (Cstring, Cint), path, mode) == 0;
Small test:
julia> access("/root", W_OK)
false
julia> access("/tmp", W_OK)
true
(for windows it could be just a little more complicated... But I could not test it now)
EDIT:
Thanks to Matt B. we could use libuv support in Julia which has to be portable (although slower on posix systems):
julia> function uv_access(path, mode)
local ret
req = Libc.malloc(Base._sizeof_uv_fs)
try
ret = ccall(:uv_fs_access, Int32, (Ptr{Void}, Ptr{Void}, Cstring, Int64, Ptr{Void}), Base.eventloop(), req, path, mode, C_NULL)
ccall(:uv_fs_req_cleanup, Void, (Ptr{Void},), req)
finally
Libc.free(req)
end
return ret, ret==0 ? "OK" : Base.struverror(ret)
end
julia> uv_access("/tmp", W_OK)
(0, "OK")
julia> uv_access("/root", W_OK)
(-13, "permission denied")
julia> uv_access("/nonexist", W_OK)
(-2, "no such file or directory")
Is the following sufficient:
julia> testdir(dirpath) = try (p,i) = mktemp(dirpath) ; rm(p) ; true catch false end
testdir (generic function with 1 method)
julia> testdir("/tmp")
true
julia> testdir("/root")
false
Returns true if dirpath is writable (by creating a temporary file inside a try-catch block). To find the first writable directory in a list, the following can be used:
julia> findfirst(testdir, ["/root","/tmp"])
2
Doing apropos("permissions"):
julia> apropos("permissions")
Base.Filesystem.gperm
Base.Filesystem.mkpath
Base.Filesystem.operm
Base.Filesystem.uperm
Base.Filesystem.mkdir
Base.Filesystem.chmod
shows a function called Base.Filesystem.uperm which seems to do exactly what you want it to:
help?> uperm
search: uperm supertype uppercase UpperTriangular isupper unescape_string unsafe_pointer_to_objref
uperm(file)
Gets the permissions of the owner of the file as a bitfield of
Value Description
––––– ––––––––––––––––––
01 Execute Permission
02 Write Permission
04 Read Permission
For allowed arguments, see stat.
Unfortunately it seems to be a bit buggy on my (old v7 nightly) build:
julia> uperm("/root")
0x07 # Uhhh I hope not?
I will update my build and raise a bug if one is not already present.
PS. In case it wasn't clear, I would expect to use this in combination with isdir to detect directory permissions specifically
I don't think that Dan Getz's answer will work on Windows because the temporary file created cannot be deleted while there is an open handle to it, but this amended version with a call to close does work:
function isfolderwritable(folder)
try
(p,i) = mktemp(folder)
close(i)
rm(p)
return(true)
catch
return(false)
end
end