5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

attributeに関数を指定できなかったが、別の方法を考えてみた

Posted at

こちらの内容の課題

 fx = fn x -> rem(x, 2) == 0 end

の部分がパラメータ化できてない

現時点の結論だめでした… 

あえて、失敗例を載せます

defmodule HogeTest do
  use ExUnit.Case
  doctest Hoge

  params = [
    [true, 1, "s"],
    [true, nil, true],
    [true, 1, false]
  ]

  for param <- params do
    @param param
    test "Hoge.all?/1 param #{inspect(@param)}" do
      assert Hoge.all?(@param) == Enum.all?(@param)
    end
  end

  params = [
    [[2, 4, 6], fn x -> rem(x, 2) == 0 end],
    [[2, 4, 5], fn x -> rem(x, 2) == 0 end]
  ]

  for [param, fx] <- params do

    @param param
    @fx fx
    test "Hoge.all?/2 param #{inspect(@param)}" do
      assert Hoge.all?(@param, @fx) == Enum.all?(@param, @fx)
    end
  end

end
** (ArgumentError) cannot inject attribute @fx into function/macro because cannot escape #Function<2.123583373 in file:test/hoge_test.exs>. The supported values are: lists, tuples, maps, atoms, numbers, bitstrings, PIDs and remote functions in the format &Mod.fun/arity
    (elixir 1.13.4) lib/kernel.ex:3509: Kernel.do_at/5
    (elixir 1.13.4) expanding macro: Kernel.@/1
    test/hoge_test.exs:28: HogeTest."test Hoge.all?/2 param [2, 4, 6]"/1
    (ex_unit 1.13.4) expanding macro: ExUnit.Assertions.assert/1
    test/hoge_test.exs:28: HogeTest."test Hoge.all?/2 param [2, 4, 6]"/1

エラーメッセージの通り、だめっぽい
だが…

無理やり動かす方法を考えた

defmodule HogeTest do
  use ExUnit.Case
  doctest Hoge

  params = [
    [true, 1, "s"],
    [true, nil, true],
    [true, 1, false]
  ]

  for param <- params do
    @param param
    test "Hoge.all?/1 param #{inspect(@param)}" do
      assert Hoge.all?(@param) == Enum.all?(@param)
    end
  end

  params = [
    [[2, 4, 6], "fn x -> rem(x, 2) == 0 end"],
    [[2, 4, 5], "fn x -> rem(x, 2) == 0 end"]
  ]

  for param <- params do
    @param param
    test "Hoge.all?/2 param #{inspect(@param)}" do
      [list, fx_string] = @param
      fx = Code.eval_string(fx_string) |> elem(0)
      assert Hoge.all?(list, fx) == Enum.all?(list, fx)
    end
  end
end

つまり、文字列として渡す
その後にCode.eval_stringで文字列から関数を作成する

5
1
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?