【问题标题】:Calling methods dynamically (Crystal-lang)动态调用方法(Crystal-lang)
【发布时间】:2019-04-30 11:11:57
【问题描述】:

我知道这可能与Any equivalent of Ruby's public_send method? 重复。我想解释一下我在做什么,也许有人可以提供建议。

过去几天我一直在移植一个 ruby​​ 应用程序来学习 Crystal。由于缺少send,我不得不删减很多功能,但今天我的程序遇到了主要问题。

我有一个哈希,其中包含作为键的击键和作为值的方法。根据敲击的键,调用适当的方法。这显然使用send 来实现相同的功能。

从链接的问题中,我了解到 Crystal 已编译,因此不允许动态方法调用。但是,如果您查看 Vim 编辑器,用户也可以将键映射到方法。 vi(m) 是用 C 语言编写的。

我想知道我是否错过了什么。

我知道我可以用每个键对 switch 语句进行硬编码并调用适当的方法,但这仍然不允许用户将键分配给方法。这种非常大的 switch-case 方法有什么替代方法吗?

(我猜我不是检查when 部分中的密钥,而是检查绑定并调用该方法。

 binding = @bindings[key]
 case binding
 when :up
    up
 when :down
    down
 when .....
 else
 end

有更好的解决方案吗?

【问题讨论】:

  • 澄清您的 Vim 示例 - 我猜 Vimscript 是处理键绑定的东西,它是一种动态语言。如果它通过 C 语言,他们可以将键映射到函数并从中查找方法。
  • 在 C 中,这很容易映射到函数指针。函数都编译好了,调用代码也编译好了,变化的输入值只是根据它在内存中的位置来选择使用哪个函数

标签: crystal-lang


【解决方案1】:

我不确定这种方式最简单方便(也许更有经验的开发人员会在下面纠正我)但我会使用Proc

def method1
  puts "i'm  method1"
end

def method2
  puts "i'm method2"
end

def method3
  puts "i'm  method3"
end

hash = { 
  "ctrl":  -> { method1 },
  "shift": -> { method2 },
  "alt":   -> { method3 }
}

binding = ["ctrl", "shift", "alt"].sample
hash[binding].call #=> i'm method2

working example

【讨论】:

  • 非常感谢。这行得通。如果没有更好的结果,我会将其标记为正确答案。我希望有人在链接的问题中提到这一点。
  • 我只是写一个小便条。 Crystal不像Ruby在执行过程中不能修改它的代码,编译后的过程代码代表的只是低级指令。在运行 Rubysend 时可以在类层次结构中找到所需的方法并调用他。 Crystal 代码没有我们熟悉的类、方法或其他对象,根本没有什么可调用的。
  • 但是 Crystal 有很棒的宏,可以模拟我们在可解释语言中习惯的很多东西。例如 Crystal 可以找到实例变量并用它做任何事情。这篇文章帮助我理解了这个概念:github.com/crystal-lang/crystal/wiki/Metaprogramming-Help
  • 关于特定用例的说明:实现可配置用户输入(如键绑定)的常见习惯用法是使用从键到内部标识符的映射(例如 "ctrl+c" => "clipboard.copy")。这些内部标识符可以硬编码到程序中(例如在switch 中使用),同时可以更改它们的映射。
  • @JohannesMüller 的建议听起来像是我在问题中提出的硬编码示例。对吗,约翰内斯?
猜你喜欢
  • 2022-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-20
相关资源
最近更新 更多