动态调用方法(Crystal语言)

3
我知道这可能是Ruby的public_send方法有等价物吗?的重复。我想解释一下我正在做什么,也许有人可以提供建议。
最近几天,我一直在将一个Ruby应用程序移植到Crystal以进行学习。由于缺少send,我不得不削减了很多功能,但今天我遇到了我的程序的一个主要部分。
我有一个哈希表,其中包含按键作为键和方法作为值。根据按下的键,调用相应的方法。这显然使用send来实现。
从链接的问题中,我了解到Crystal是编译的,因此不允许动态方法调用。但是,如果您查看Vim编辑器,用户也可以将键映射到方法。而vi(m)是用C写的。
我想知道我是否错过了什么。
我知道我可能可以硬编码一个switch语句,并调用适当的方法,但这仍然不允许用户将密钥分配给方法。是否有任何替代这个非常大的开关情况方法?
(我猜想,与其在when部分检查键,不如检查绑定并调用该方法。)
 binding = @bindings[key]
 case binding
 when :up
    up
 when :down
    down
 when .....
 else
 end

最初的回答
有更好的解决方案吗?

澄清一下你的 Vim 示例 - 我猜测 Vimscript 正在处理键绑定,它是一种动态语言。如果经过 C 处理,他们可以进行键到函数的映射,并从中查找方法。 - Will Richardson
在 C 语言中,这很容易映射到一个函数指针。所有函数都已经编译好了,调用代码也是如此,而改变输入值只是通过引用其在内存中的位置来选择要使用的函数。 - vectorselector
1个回答

3
我不确定这是最简单和方便的方法(也许更有经验的开发人员会在下面纠正我),但我会使用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

请查看实际示例

最初的回答


1
非常感谢。这个方法可行。如果没有更好的答案出现,我会将其标记为正确答案。但愿在相关问题中有人提到过这个方法。 - rahul
1
我只是加入一个小注释。Crystal不像Ruby一样在执行期间无法修改其代码,在编译过程之后,代码所代表的只是低级指令。在运行Ruby时,“send”可以在类层次结构中找到所需的方法并调用它。Crystal代码没有我们熟悉的类、方法或其他对象,没有可供调用的东西。 - Sergey Fedorov
1
但是Crystal有很棒的宏,可以模拟我们在可解释语言中习惯的许多东西。例如,Crystal可以找到实例变量并对其进行任何操作。这篇文章帮助我理解了这个概念:https://github.com/crystal-lang/crystal/wiki/Metaprogramming-Help - Sergey Fedorov
1
关于特定用例的说明:实现可配置用户输入(例如键绑定)的常见习语是使用从按键到内部标识符的映射(例如“ctrl+c”=>"clipboard.copy")。这些内部标识符可以硬编码到程序中(例如在switch中使用),而它们的映射可以被改变。 - Johannes Müller
@JohannesMГјllerзҡ„е»әи®®еҗ¬иө·жқҘеғҸжҲ‘еңЁй—®йўҳдёӯжҸҗеҮәзҡ„зЎ¬зј–з ҒзӨәдҫӢгҖӮиҝҷжҳҜжӯЈзЎ®зҡ„еҗ—пјҢJohannesпјҹ - rahul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接