Problem with autoconversion to character

I am pulling data from a db table. A sample record looks like this: [{2019, 3, 1}, 12].
I am doing a [head|tail] on the record so that I can process it.
The head is fine - I can do what I need to do with it.

The problem is the tail (the 12).

It is being processed by the code as '\f' but my code needs a real number, not the character version of it.

?tail works great in iex and IO.inspect but it doesn’t work inside of code.

How can I get either, the number 12 or at worst, the string of the number "12"?

I could cheat and pull that field as a string, but I’d be missing a ‘teaching moment’ (and its a bit of a flaky work-around)

Thank you for any help you can provide!

elixir_char

You already do have the number 12, or a list with the single element of a number 12. You’re being confused by how it displays in the debugger.

That error indicates that you’re sending a list of a single integer to byte_size, which expects a binary.

But the beginning of you message indicates that you should have a number, not a list. So we need to see more of your code for context about what you’re actually trying to do with your data…

I know about why it shows up in a debugger that way - its the actual code that fails to compile because of it.

Here is what I am doing in my code - essentially building a string:

  def page_pr_map([head | tail], accumulator) do
    [date|val] = head

    dat = Tuple.to_list(date)
    [year, month, day] = dat

    page_pr_map(tail, "[Date.UTC("<>
                           Integer.to_string(year) <> ", " <> Integer.to_string(month) <> "," <> Integer.to_string(day)
                            <>"), "
                            <> val
                            <> "], "
                            <> accumulator)
  end

It’s the val variable that is being received by my code as \f.

Seems like you are trying to concatenate a string and a charlist (and then a string, etc.). You would have to convert val to a string for this code to work, I think, because the <> operator concatenates strings, not lists.

I just fixed it! if I do this:

[date|val} = head
[val|_] = val

and in the output string that gets sent to the next recursion, I just Integer.to_string(val)

then it works :slight_smile:

You still get credit because your comment

That error indicates that you’re sending a list of a single integer to byte_size

Is what clued me in.

Not sure if that’s the correct way to solve it though…

Thanks!

ah, you’re being tripped by a subtlety of pattern matching on lists, remember that a linked list is a list of lists, so tail is always a list, possibly empty (well, except for the empty list which has no tail)–here, check out this:

iex(1)> [date|val] = [1,2]
[1, 2]
iex(2)> date
1
iex(3)> val
[2]
iex(4)> [date|[val]] = [1,2]
[1, 2]
iex(5)> date
1
iex(6)> val
2
# the way you really want to do it:
iex(7)> [date,val] = [1,2]
[1, 2]
iex(8)> date
1
iex(9)> val
2

Also

dat = Tuple.to_list(date)
[year, month, day] = dat

should just be {year, month, day} = date

and pretty sure you need Integer.to_string(val)

[EDIT] and I see you’re already calling Integer.to_string–it was just “below the fold” of your message when I was composing this :wink:

2 Likes

Just as a note a side, you can just do {year, month, day} = date, no need to convert the tuple to a list first. Pattern matching is not limited to lists.

3 Likes