如何获取传递给块的参数的名称?

Mar*_*tix 4 crystal-lang

在Ruby中,您可以这样做:

prc = lambda{|x, y=42, *other|}
prc.parameters  #=> [[:req, :x], [:opt, :y], [:rest, :other]]
Run Code Online (Sandbox Code Playgroud)

尤其是,我很感兴趣,能够得到它们的参数的名称x,并y在上面的例子.

在Crystal中,我有以下情况:

def my_method(&block)
  # I would like the name of the arguments of the block here
end
Run Code Online (Sandbox Code Playgroud)

如何在Crystal中做到这一点?

Jon*_*Haß 6

虽然这在Ruby中听起来很奇怪,但是在Crystal中没有办法做到这一点,因为在你的例子中,块已经没有参数.另一个问题是编译后这些信息已经丢失.所以我们需要在编译时访问它.但是您无法在编译时访问运行时方法参数.但是,您可以使用宏访问该块,然后甚至允许块的任意签名,而无需明确地给出它们:

macro foo(&block)
  {{ block.args.first.stringify }}
end

p foo {|x| 0 } # => "x"
Run Code Online (Sandbox Code Playgroud)


Joh*_*ler 5

为了扩展JonneHaß的优秀答案,相当于Ruby的parameters方法将是这样的:

macro block_args(&block)
  {{ block.args.map &.symbolize }}
end
p block_args {|x, y, *other| } # => [:x, :y, :other]
Run Code Online (Sandbox Code Playgroud)

请注意,Crystal中始终需要块参数,并且不能具有默认值.