Cannot invoke remote function :erlang.length/1 inside match

I’m trying to take a float, add it to the array of floats in a model instance, and save it back to the database. I only want the array to have a max length of 90. Here is my code for that so far.

 def add_price(model, %{"price" => price}) do
    current_price = model.price
    price_list =
      case current_price do
        nil -> [price]
        90 > length(current_price) -> [current_price | price]
        _ ->
          prices = List.delete_at(current_price, 0)
          [prices | price]
      end
    model.price = price_list
  end

I’ve tried doing this a few ways, but I keep getting the error “Cannot invoke remote function :erlang.length/1 inside match.” How do I go about checking the length?

1 Like

You cannot run length/1 inside a pattern match. You should move it to a guard:

list when length(list) < 90 -> [list | price]

Thanks! That worked

Why not?

Because only a limited set of functions is callable in a guard, those are called guardsafe functions. This is a limitation of the BEAM to make some optimisations possible.

Basically it is, because the BEAM weren’t allowed to reorder clauses if functions in a guard were allowed to have side effects.

2 Likes