elixirkoans / elixir-koans

Elixir learning exercises
MIT License
2.22k stars 599 forks source link

Match failure in 15_processes.ex - ex_unit_no_meaningful_value #266

Closed briankung closed 2 years ago

briankung commented 2 years ago

Something isn't matching in Processes 173 Here's my code:

koan "A common pattern is to include the sender in the message, so that it can reply" do
  greeter = fn ->
    receive do
      {:hello, sender} -> send(sender, :how_are_you?)
    end
  end

  pid = spawn(greeter)

  send(pid, {:hello, self()})
  assert_receive :how_are_you
end

And here's what I get:

Now meditate upon Processes
|========================>     | 173 of 209
----------------------------------------
A common pattern is to include the sender in the message, so that it can reply
Assertion failed in lib/koans/15_processes.ex:80
assert_receive(:how_are_you)

left:  :how_are_you
right: :ex_unit_no_meaningful_value

Interestingly, even if I change it to really forgiving match arms, it still gives me :ex_unit_no_meaningful_value:

self_pid = self()
greeter = fn ->
  receive do
    _anything -> send(self_pid, :how_are_you?)
  end
end

I'm on macOS and Elixir version 1.12.2 with Erlang/OTP 24. Any help would be appreciated!

briankung commented 2 years ago

This is happening with the next koan, too 😭 I wonder if there is some sort of configuration I'm missing. The spawned process receives a message, but it doesn't match against the PID for some reason. I even tried using when is_pid(sender) on the match arm (as recommended here), but it still failed. When I use the match arm any -> IO.puts(any) in iex it prints out the {:hello, #PID<0.105.0>}. Actually, this whole thing works as expected in iex, just not in the test framework.

iamvery commented 2 years ago

Hey Brian, very late reply here 😅 . Can you try this again? Some changes were made in #271 that may address the problem you were seeing.

briankung commented 2 years ago

Thanks for coming back to notify me! I've since moved on, but I'll try to run this when I get a chance.

briankung commented 2 years ago

Hi @iamvery unfortunately no, it still doesn't seem to work. I don't know how to run a single koan, but I replaced my 01_equalities.ex file with these contents and it still doesn't pass:

defmodule Equalities do
  use Koans

  @intro """
  Welcome to the Elixir koans.
  Let these be your first humble steps towards learning a new language.

  The path laid in front of you is one of many.
  """

  koan "A common pattern is to include the sender in the message, so that it can reply" do
    self_pid = self()

    greeter = fn ->
      receive do
        _anything -> send(self_pid, :how_are_you?)
      end
    end

    pid = spawn(greeter)

    send(pid, {:hello, self()})
    assert_receive :how_are_you
  end
end

And I get this output:

Welcome to the Elixir koans.
Let these be your first humble steps towards learning a new language.

The path laid in front of you is one of many.

Now meditate upon Equalities
|                              | 0 of 203
----------------------------------------
A common pattern is to include the sender in the message, so that it can reply
Assertion failed in lib/koans/01_equalities.ex:23
assert_receive :how_are_you

left:  :how_are_you
right: :ex_unit_no_meaningful_value

Now, I haven't touched the Koans in a while, so my process was to git pull then mix deps.get then finally mix meditate. Not sure what it could be. If you have any ideas for debugging, I'd be happy to try them out.

iamvery commented 2 years ago

Ah hah! Thanks for writing back, I see the problem with your solution now, and the error message definitely leaves something to be desired. The value sent back is the atom :how_are_you? (note: the trailing "question mark" is included). That should be enough to get the example passing.

I don't know how to run a single koan

You can run a single Koan file by its module name like mix meditate --koan=Processes, but it will still run them from the top of that file. From there, you could comment out the first few to target specific example.

I hope this helps!

iamvery commented 2 years ago

I see, it's because the value given to assert_receive is used for a match. Since the pattern match fails, you get a pretty crummy error message. I'll add a failure message to the call which may help clear it up. PR incoming

briankung commented 2 years ago

Wow, I had a question mark in there this whole time? 🤦‍♂️ thanks for the hint and the PR!