How do I run a beam file compiled by Elixir or Erlang? - erlang

I have installed Erlang/OTP and Elixir, and compiled the HelloWorld program into a BEAM using the command:
elixirc test.ex
Which produced a file named Elixir.Hello.beam
How do I run this file?

Short answer: no way to know for sure without also knowing the contents of your source file :)
There are a few ways to run Elixir code. This answer will be an overview of various workflows that can be used with Elixir.
When you are just getting started and want to try things out, launching iex and evaluating expressions one at a time is the way to go.
iex(5)> Enum.reverse [1,2,3,4]
[4, 3, 2, 1]
You can also get help on Elixir modules and functions in iex. Most of the functions have examples in their docs.
iex(6)> h Enum.reverse
def reverse(collection)
Reverses the collection.
[...]
When you want to put some code into a file to reuse it later, the recommended (and de facto standard) way is to create a mix project and start adding modules to it. But perhaps, you would like to know what's going on under the covers before relying on mix to perform common tasks like compiling code, starting applications, and so on. Let me explain that.
The simplest way to put some expressions into a file and run it would be to use the elixir command.
x = :math.sqrt(1234)
IO.puts "Your square root is #{x}"
Put the above fragment of code into a file named simple.exs and run it with elixir simple.exs. The .exs extension is just a convention to indicate that the file is meant to be evaluated (and that is what we did).
This works up until the point you want to start building a project. Then you will need to organize your code into modules. Each module is a collection of functions. It is also the minimal compilation unit: each module is compiled into a .beam file. Usually people have one module per source file, but it is also fine to define more than one. Regardless of the number of modules in a single source file, each module will end up in its own .beam file when compiled.
defmodule M do
def hi(name) do
IO.puts "Hello, #{name}"
end
end
We have defined a module with a single function. Save it to a file named mymod.ex. We can use it in multiple ways:
launch iex and evaluate the code in the spawned shell session:
$ iex mymod.ex
iex> M.hi "Alex"
Hello, Alex
:ok
evaluate it before running some other code. For example, to evaluate a single expression on the command line, use elixir -e <expr>. You can "require" (basically, evaluate and load) one or more files before it:
$ elixir -r mymod.ex -e 'M.hi "Alex"'
Hello, Alex
compile it and let the code loading facility of the VM find it
$ elixirc mymod.ex
$ iex
iex> M.hi "Alex"
Hello, Alex
:ok
In that last example we compiled the module which produced a file named Elixir.M.beam in the current directory. When you then run iex in the same directory, the module will be loaded the first time a function from it is called. You could also use other ways to evaluate code, like elixir -e 'M.hi "..."'. As long as the .beam file can be found by the code loader, the module will be loaded and the appropriate function in it will be executed.
However, this was all about trying to play with some code examples. When you are ready to build a project in Elixir, you will need to use mix. The workflow with mix is more or less as follows:
$ mix new myproj
* creating README.md
* creating .gitignore
* creating mix.exs
[...]
$ cd myproj
# 'mix new' has generated a dummy test for you
# see test/myproj_test.exs
$ mix test
Add new modules in the lib/ directory. It is customary to prefix all module names with your project name. So if you take the M module we defined above and put it into the file lib/m.ex, it'll look like this:
defmodule Myproj.M do
def hi(name) do
IO.puts "Hello, #{name}"
end
end
Now you can start a shell with the Mix project loaded in it.
$ iex -S mix
Running the above will compile all your source file and will put them under the _build directory. Mix will also set up the code path for you so that the code loader can locate .beam files in that directory.
Evaluating expressions in the context of a mix project looks like this:
$ mix run -e 'Myproj.M.hi "..."'
Again, no need to compile anything. Most mix tasks will recompile any changed files, so you can safely assume that any modules you have defined are available when you call functions from them.
Run mix help to see all available tasks and mix help <task> to get a detailed description of a particular task.

To specifically address the question:
$ elixirc test.ex
will produce a file named Elixir.Hello.beam, if the file defines a Hello module.
If you run elixir or iex from the directory containing this file, the module will be available. So:
$ elixir -e Hello.some_function
or
$ iex
iex(1)> Hello.some_function

Assume that I write an Elixir program like this:
defmodule PascalTriangle do
defp next_row(m), do: for(x <- (-1..Map.size(m)-1), do: { (x+1), Map.get(m, x, 0) + Map.get(m, x+1, 0) } ) |> Map.new
def draw(1), do: (IO.puts(1); %{ 0 => 1})
def draw(n) do
(new_map = draw(n - 1) |> next_row ) |> Map.values |> Enum.join(" ") |> IO.puts
new_map
end
end
The module PascalTriangle can be used like this: PascalTriangle.draw(8)
When you use elixirc to compile the ex file, it will create a file called Elixir.PascalTriangle.beam.
From command line, you can execute the beam file like this:
elixir -e "PascalTriangle.draw(8)"
You can see the output similar to the photo:

Related

How to Compile Agda Hello World on Nixos?

On nixos, I am trying to compile the hello world example listed in the agda documentation.
In my working directory, I have the following:
The hello-world agda program, hello-world.agda:
module hello-world where
open import IO
main = run (putStrLn "Hello, World!")
A nix shell file, shell.nix:
{ pkgs ? import <nixpkgs> { } }:
with pkgs;
mkShell {
buildInputs = [
(agda.withPackages (ps: [
ps.standard-library
]))
];
}
To enter a shell with the standard-library dependency available, I ran $ nix-shell shell.nix.
Then, trying to compile the program, I ran $ agda --compile hello-world.agda, as advised by the linked agda hello world documentation.
But that gave me the following error:
$ agda --compile hello-world.agda
Checking hello-world (/home/matthew/backup/projects/agda-math/hello-world.agda).
/home/matthew/backup/projects/agda-math/hello-world.agda:3,1-15
Failed to find source of module IO in any of the following
locations:
/home/matthew/backup/projects/agda-math/IO.agda
/home/matthew/backup/projects/agda-math/IO.lagda
/nix/store/7pg293b76ppv2rw2saf5lcbckn6kdy7z-Agda-2.6.2.2-data/share/ghc-9.0.2/x86_64-linux-ghc-9.0.2/Agda-2.6.2.2/lib/prim/IO.agda
/nix/store/7pg293b76ppv2rw2saf5lcbckn6kdy7z-Agda-2.6.2.2-data/share/ghc-9.0.2/x86_64-linux-ghc-9.0.2/Agda-2.6.2.2/lib/prim/IO.lagda
when scope checking the declaration
open import IO
It seems it should be finding the standard library, since I'm running from the nix-shell with agda's standard-library specified, but that error on open import IO looks like the standard library is somehow still not found.
Any idea what the problem is likely to be?
Or what else I can do to get agda working on nixos?
You might need to create a defaults file in AGDA_DIR (which typically refers to ~/.agda/ unless overwritten through environment variable) with the libraries you want to make available to your program:
echo standard-library >> ~/.agda/defaults
which should make the compiler automatically load the standard library.
Alternatively, you can pass them in on the command-line:
agda -l standard-library
or use a project-local .agda-lib file as follows:
name: my-libary
depend: standard-library
include: -- Optionally specify include paths
You should not need to specify the include paths with Nix, but in case you do, you can use the -i command line flag or add the path to the standard-library.agda-lib file in ~/.agda/libraries.

Using Elixir module from Erlang fails

I am trying to use in Erlang module a beam-file compiled from Elixir source. It raises error when I run Erlang node but I can use the code directly from Elixir.
Elixir module:
defmodule Recursion do
def print_multiple_times(msg, n) when n <= 1 do
IO.puts msg
end
def print_multiple_times(msg, n) do
IO.puts msg
print_multiple_times(msg, n - 1)
end
end
Erlang module:
-module(use_recur).
-define(elixir__recursion, 'Elixir.Recursion').
-export([hey/0]).
hey() ->
?elixir__recursion:print_multiple_times("Hello!", 3).
Compile both:
$ rm -f *.beam
$ elixirc recursion.ex
$ erlc use_recur.erl
Run Erlang:
$ erl -run use_recur hey -run init stop -noshell {"init terminating in do_boot",{undef,[{'Elixir.IO',puts,["Hello!"],[]},{'Elixir.Recursion',print_multiple_times,2,[{file,"recursion.ex"},{line,7}]},{init,start_em,1,[]},{init,do_boot,3,[]}]}}
init terminating in do_boot ({undef,[{Elixir.IO,puts,Hello!,[]},{Elixir.Recursion,print_multiple_times,2,[{},{}]},{init,start_em,1,[]},{init,do_boot,3,[]}]})
Crash dump is being written to: erl_crash.dump...done
Elixir script:
Recursion.print_multiple_times "Hello!", 3
Runs successfully:
$ elixir elx_recur.exs
Hello!
Hello!
Hello!
Why does it happen? I'd say Erlang's output should be the same.
The error means that Erlang could not find a module named 'Elixir.IO'. This module is part of core Elixir. You'll need to add the ebin folder of your Elixir installation to Erlang's load path using -pa (or other similar flags like -pz) to make Erlang load Elixir's core libraries, as that folder contains the compiled .beam files of Elixir core, including Elixir.IO.beam.
erl -pa /path/to/elixir/ebin ...

How to execute 5 different ruby files in series

I'm new to ruby and I'm trying to run 5 different files in a folder. I'd like to execute them all in series mean one after another.
the list of my files are:
Scripts/aaa. rb
Scripts/bbb. rb
Scripts/ccc. rb
Scripts/ddd. rb
Scripts/eee. rb
My script should run the aaa.rb first and then rest
Do as below using Dir::chdir, Dir::glob:
Dir.chdir("path/to/the/.rb files") do |path|
Dir.glob("*.rb").sort.each do |name|
system("ruby #{name}")
end
end
create another ruby script to run them in order
["aaa", "bbb", "ccc", "ddd", "eee"].each do |name|
system("ruby #{name}.rb") #give the full path of the file here
end
Depending on your OS, you can use a batch file, or a shell script. In either case, that's exactly their purpose. Assuming you have the executable bit set on the files:
On *nix or Mac OS:
#!/bin/sh
Scripts/aaa.rb
Scripts/bbb.rb
Scripts/ccc.rb
Scripts/ddd.rb
Scripts/eee.rb
as a simplistic script.
For something a bit more "DRY":
#!/bin/sh
pushdir Scripts
for i in aaa bbb ccc ddd eee
do
$i.rb
done
popdir
If the executable-bit isn't set, precede the name of the file with the path to your Ruby executable, something like:
/usr/local/bin/ruby Scripts/aaa.rb
There are a lot of other ways to point to the Ruby executable, so your mileage might vary.

erl_tidy cannot determine module name for escript

I want use erl_tidy to format erlang code, including escript files.
But this comes out when I format one escript file (source) after adding -module(erl_pprint). :
1> erl_tidy:file("erl_pprint").
erl_pprint: error: cannot determine module name.
** exception exit: error
But When I remove the she-bang line #!/usr/bin/env escript, formatting goes well.
So how can I formatteing the code while keep the she-bang line?
You can't treat an escript file as a normal module and give it to erl_tidy. Perhaps you can drop the comment lines using "tail -n+2 erl_pprint > /tmp/erl_pprint.erl", run erl_tidy on the temp file, and then use "cat escript-header.txt /tmp/erl_pprint.erl > erl_pprint.new", if you create a file called escript-header.txt containing the leading shebang line (or lines).

rails - Redirecting console output to a file

On a bash console, if I do this:
cd mydir
ls -l > mydir.txt
The > operator captures the standard input and redirects it to a file; so I get the listing of files in mydir.txt instead of in the standard output.
Is there any way to do something similar on the rails console?
I've got a ruby statement that generates lots of prints (~8k lines) and I'd like to be able to see it completely, but the console only "remembers" the last 1024 lines or so. So I thought about redirecting to a file - If anyone knows a better option, I'm all ears.
A quick one-off solution:
irb:001> f = File.new('statements.xml', 'w')
irb:002> f << Account.find(1).statements.to_xml
irb:003> f.close
Create a JSON fixture:
irb:004> f = File.new(Rails.root + 'spec/fixtures/qbo/amy_cust.json', 'w')
irb:005> f << JSON.pretty_generate((q.get :customer, 1).as_json)
irb:006> f.close
You can use override $stdout to redirect the console output:
$stdout = File.new('console.out', 'w')
You may also need to call this once:
$stdout.sync = true
To restore:
$stdout = STDOUT
Apart from Veger's answer, there is one of more way to do it which also provides many other additional options.
Just open your rails project directory and enter the command:
rails c | tee output.txt
tee command also has many other options which you can check out by:
man tee
If you write the following code in your environment file, it should work.
if "irb" == $0
config.logger = Logger.new(Rails.root.join('path_to_log_file.txt'))
end
You can also rotate the log file using
config.logger = Logger.new(Rails.root.join('path_to_log_file.txt'), number_of_files, file_roation_size_threshold)
For logging only active record related operations, you can do
ActiveRecord::Base.logger = Logger.new(Rails.root.join('path_to_log_file.txt'))
This also lets you have different logger config/file for different environments.
Using Hirb, you can choose to log only the Hirb output to a text file.
That makes you able to still see the commands you type in into the console window, and just the model output will go to the file.
From the Hirb readme:
Although views by default are printed to STDOUT, they can be easily modified to write anywhere:
# Setup views to write to file 'console.log'.
>> Hirb::View.render_method = lambda {|output| File.open("console.log", 'w') {|f| f.write(output) } }
# Doesn't write to file because Symbol doesn't have a view and thus defaults to irb's echo mode.
>> :blah
=> :blah
# Go back to printing Hirb views to STDOUT.
>> Hirb::View.reset_render_method
Use hirb. It automatically pages any output in irb that is longer than a screenful. Put this in a console session to see this work:
>> require 'rubygems'
>> require 'hirb'
>> Hirb.enable
For more on how this works, read this post.
Try using script utility if you are on Unix-based OS.
script -c "rails runner -e development lib/scripts/my_script.rb" report.txt
That helped me capture a Rails runner script's very-very long output easily to a file.
I tried using redirecting to a file but it got written only at the end of script.
That didn't helped me because I had few interactive commands in my script.
Then I used just script and then ran the rails runner in script session but it didn't wrote everything. Then I found this script -c "runner command here" output_file and it saved all the output as was desired. This was on Ubuntu 14.04 LTS
References:
https://askubuntu.com/questions/290322/how-to-get-and-copy-a-too-long-output-completely-in-terminal#comment1668695_715798
Writing Ruby Console Output to Text File

Resources