String.contains? not outputting what I expect it to

Hi,

I have the following code, and even though I can see (via the inspect) that the response_body does contain one of the strings I’m looking for, I’m not getting the “Waiting for Daemon to be ready message”?

Any ideas what I’m doing wrong please?

case HTTPoison.post(url, body, headers) do
{:ok, %{body: response_body}} → 
IO.inspect(response_body)

      if String.contains?(response_body, "Loading") ||
           String.contains?(response_body, "Preparing databases") ||
           String.contains?(response_body, "Rewinding") ||
           String.contains?(response_body, "RPC server started") ||
           String.contains?(response_body, "Verifying") do
        Logger.info("Waiting for Daemon to be ready, attempt #{attempt}")
        Process.sleep(3000)
        {:cont, {:error, :wrong_response}}
1 Like

Can you please share the exact output?

1 Like

What’s the output of Logger.level()? If it’s not info or debug, nothing will be logged

2 Likes

I think you can figure out what’s happening easily if you try to open a Elixir interpreter with your application.

If it is a Phoenix app

iex -S mix phx.server

If not

iex -S mix

Then, you should be able to execute the Elixir Code from your function there, or you should be able to just copy paste an expression which you don’t know what should be the behavior.

2 Likes

You need to figure out whether it’s the contains check or the log statement that isn’t working. If you throw a raise "foo" in the if block that should narrow it down pretty quickly.

BTW, you would probably get better performance by writing a single regex for those terms and using Regex.match?/2 to do the check in one pass.

1 Like

Hi, thanks for everyone’s input. I’ve got it working now, but I’m not sure how :slight_smile: I’m still a newbie, so probably did something wrong.

Am I correct in thinking I should be using || for or instead of or ?

Richard

There are a couple of differences:

  • || operates on truthiness or falseness in the Elixir sense. That is, nil and false are considered falsy and everything else is truthy.
  • || will short circuit. If the left hand side expression is falsy then the right hand side expression is not evaluated.
  • or expressions must be booleans (true or false)
  • or does not short circuit
  • || is not available for use in guard expressions.

That means that || and or both have a place in the language.

3 Likes

It short-circuits, too.

1 Like

These both statements are not precisely correct, because Kernel.or/2 gets translated to :erlang.orelse/2, not to :erlang.or/2.

  • LHO of or/2 must be a boolean, the RHO might be anything;
  • or/2 does short circuit.

If one wants the erlangish behaviour, they should opt in for :erlang.or/2.

3 Likes

To add on to the above, make sure you check out the operators reference in the docs and click on any you’re curious about. One of the cool things about Elixir is that pretty much every language construct is implemented as a function or macro and they all have excellent docs.

3 Likes