Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Basic Printing with Elixir - IO.puts error: ** (ArgumentError) argument error (stdlib) :io.put_chars(#PID

Here's the program I'm trying to run for Elixir 1.0.3:

IO.puts "putstest"

div2 = fn inputnum ->
  [:a, inputnum/4, inputnum/7, inputnum/5.0, inputnum/7, inputnum*88]
end

myoutput = div2.(300.0)

IO.puts myoutput

I added the :a atom in case Elixir was doing some sort of implicit casting.

I'm sort of new to Elixir. I keep getting the following error when I run the code above by $ elixir putztestzorz.exs:

putstest
** (ArgumentError) argument error
    (stdlib) :io.put_chars(#PID<0.24.0>, :unicode, [[:a, 75.0, 42.857142857142854, 60.0, 42.857142857142854, 2.64e4], 10])
    (elixir) lib/code.ex:316: Code.require_file/2

I checked the IO documentation, but neither IO.stream (Converts the io device into a IO.Stream, changed the last line to IO.stream output) nor IO.write (Writes the given argument to the given device, changed the last line to IO.write :stdout, output) seem to do the trick.

I don't want to keep just guessing, here, and I seem to not quite understand what the function is supposed to be doing.

Is there an analogue to Python's print() that will just, well, work?

Do I need to cast the list, or something?

I'm probably missing something really simple, here, but I don't want to just guess my way down the list of IO handling functions.

(P.S. The documentation keeps talking about a Process.group_leader. I don't plan to do much with this yet, but is there a way to put it in context for this sort of thing? I keep imagining Red Leader from Star Wars.)

like image 595
Nathan Basanese Avatar asked Feb 21 '15 07:02

Nathan Basanese


1 Answers

The problem is that IO.puts cannot handle arbitrary lists, hence the ArgumentError. The only type of list it can handle are character lists, or single quoted strings. This is the reason why the function matches the list argument successfully, but later blows up deep down inside the library. You basically have two alternatives:

Use IO.inspect to quickly debug any value to stdout.

IO.inspect myoutput

Use a for comprehension together with Erlang's :io.format to explicitly format the output, much like printf. The :a will probably throw an error, but if you remove it, the following should work:

for x <- myoutput do
  :io.format "~.2f~n", [x]
end

Note that ~.2f prints the values with two digits after the comma. ~n adds the newline.

like image 127
Patrick Oscity Avatar answered Oct 24 '22 01:10

Patrick Oscity