如何在Elixir中模拟Ruby的直到循环?

时间:2016-07-02 12:17:27

标签: recursion elixir

我正在将Ruby项目转换为Elixir。 Ruby的until循环如何转换为Elixir?

until scanner.eos? do
  tokens << scan(line + 1)
end

这是完整的Ruby方法:

def tokenize
  @tokens = []
  @lines.each_with_index do |text, line|
    @scanner = StringScanner.new(text)
    until @scanner.eos? do
      @tokens << scan(line + 1)
    end
  end
  @tokens
end

@lines只是一个由新行分割的文本文件。 @lines = text.split("\n")

在Elixir中,我已经转换了string scanner,如下所示:StringScanner.eos?(scanner)

@spec eos?(pid) :: boolean
def eos?(pid) when is_pid(pid) do

此外,在Elixir中,令牌是元组:@type token :: {:atom, any, {integer, integer}}{integer, integer}元组是令牌的lineposition的位置。

这是Elixir伪造的代码,它不太有效。

@spec scan(String.t, integer) :: token
def scan(text, line) when is_binary(text) and is_integer(line) do
  string_scanner = StringScanner.new(text)
  until StringScanner.eos?(string_scanner) do
    result = Enum.find_value(@scanner_tokenizers, fn {scanner, tokenizer} ->
      match = scanner.(string_scanner)
      if match do
        tokenizer.(string_scanner, match, line)
      end
    end)
    IO.inspect result
  end
  StringScanner.stop(string_scanner)
  result
end

slack channel上有人建议使用递归,但他们没有详细说明示例。我已经看到了使用累加器等求和/缩减的递归示例。但是,我没有看到在评估布尔值时如何应用。

任何人都可以提供使用StringScanner.eos?(scanner)的工作示例吗?感谢。

1 个答案:

答案 0 :(得分:2)

可能类似

def tokens(scanner) do
  tokens(scanner, [])
end

defp tokens(scanner, acc) do
  if StringScanner.eos?(scanner) do
    acc
  else
    tokens(scanner, add_to_acc(scan_stuff(), acc))
  end
end

至少这可能是一般的想法。正如您所看到的那样,我保留了一些非常通用的功能(scan_stuff/0add_to_acc/2),因为我不知道您是如何实现这些功能的;第一个用于执行scan(line + 1)在Ruby代码中执行的操作,而第二个用于执行<<在Ruby代码中执行的操作(例如,它可以将扫描的内容添加到列表中令牌或类似的东西)。