How not to use pattern matching?

Pattern matching is so handy that I am worried I might be misusing it.

[_, {_, _, stocks}, {_, _, [_, {_, _, [_, closing_price, _, last_transaction_price]}]}] =
      html
      |> Floki.find("div.table-wrapper")
      |> List.first()
      |> Floki.children()
      |> List.first()
      |> Floki.children()

By using pattern matching here, it helped me skip few iterators and operations. But god it looks awful.

So, my question is how not to use pattern matching?

The pattern matching is right, but you can try to split things to make the code easy to read.

def get_stock_prices(html) do
  [_cell, stock_cell, prices_cell] =
    html
    |> Floki.find("div.table-wrapper")
    |> List.first()
    |> Floki.children()
    |> List.first()
    |> Floki.children()

  stock = Floki.text(stock_cell)
  {closing_price, last_transaction_price} = get_prices(prices_cell)

  {stock, closing_price, last_transaction_price}
end

defp get_prices({"td",_ ,html_fragment}) do ...
5 Likes

Writing code is easy, reading it months later and understanding it is hard. Optimize for that.

Will you recognize what this code does in 6 months? What about two years?

In your case, I wouldn’t use pattern matching like that, I would use iterators because it’ll be easier to maintain.

2 Likes

The problem is that you have a leaking abstraction. You shouldn’t “know” about Floki's internal representation of the data structures.

Floki properly documented its type to be like this.

This makes the representation part of the contract and can therefore assumed to hold. There is nothing “internal” involved.

I think its much more problematic, that fixed lists length is assumed. This can fail once the scraped HTML changes its structure.

5 Likes

Yeah, you are right. I was trying convey the idea that data extraction should probably be done via the functions of the library as opposed to raw pattern matching but I guess I didn’t really word it well.