Ruby:如何将函数映射到散列

时间:2011-08-11 09:57:13

标签: ruby function hash

我无法弄清楚如何为ruby哈希分配函数调用。 我想要做的是将一个函数分配给一个哈希键,以后再 使用经典的散列监视语法调用此函数。

def Foo()
  puts "bar"
end

puts "Assigning"
test = { "foo" => Foo() }

puts "Executing"
test["foo"]

此代码失败,在puts "Assign"之后调用函数Foo,在创建哈希期间,puts "Executing"

之后没有任何反应
def Foo()
  puts "bar"
end

puts "Assigning"
test = { "foo" => Foo }

puts "Executing"
test["foo"]

使用此代码我收到uninitialized constant Foo (NameError)

最后用

def Foo()
  puts "bar"
end

puts "Assigning"
test = { "foo" => :Foo }

puts "Executing"
test["foo"]

我没有输出。

有什么建议吗?

感谢大家的回答和建议。

我要做的就是测试 如果基于散列的调用函数方法比快 基于if / case语句的等效代码。

funcs["foo"].call

胖于

if func_name == "foo" then
  Foo()
elsif ...
...
end

case func_name
when "foo"
  Foo()
when ...
  ...
end

显然有很多功能(~150)和数百种功能 呼叫周期

4 个答案:

答案 0 :(得分:4)

你可以使用lambda代替方法。这里有两个选择:

hash = {:foo => lambda { puts 'bar } }

hash[:foo].call

第二个(更复杂)是:

irb(main):001:0> class Hash
irb(main):002:1>   alias :orig_anc :'[]'
irb(main):003:1>
irb(main):004:1*   def [](key)
irb(main):005:2>     if orig_anc(key).is_a? Proc
irb(main):006:3>       orig_anc(key).call
irb(main):007:3>     else
irb(main):008:3*       orig_anc(key)
irb(main):009:3>     end
irb(main):010:2>   end
irb(main):011:1> end
=> nil
irb(main):012:0> h = {:hello => 'world', :foo => lambda { puts 'bar' }}
=> {:hello=>"world", :foo=>#<Proc:0x843224c@(irb):12 (lambda)>}
irb(main):013:0> h[:hello]
=> "world"
irb(main):014:0> h[:foo]
bar
=> nil
irb(main):015:0>

第二个只允许你跳过使用'call'方法

答案 1 :(得分:3)

正如Vlad所指出的那样,简单地通过检索带有Hash [] def foo puts "hi" end ... # magic test["foo"] # outputs hi 方法的哈希密钥来执行函数是不可能的,即。

call

不起作用。但是,您可以使用Object#method分配方法引用,然后使用def foo puts "hi" end test = { "foo" => method(:foo) } test["foo"].call # => hi 调用它:

{{1}}

答案 2 :(得分:0)

首先,首先使用小写字母开始方法名称。然后,转到第一个示例,Ruby非常渴望调用test = { "foo" => Foo() } Foo

在第二个例子中,以大写字母开头的变量被认为是常量,因此Ruby寻找一个并且不用费心去寻找方法。考虑到foo如果在第一个例子中调用方法然后调用foo。

第三个例子:test["foo"]返回:Foo,一个符号。在您的代码Foo()中没有任何地方被调用。

* 建议

1.-看看Ruby中的标识符命名法。

2.-您可以查看lambdaProcObject#method

3.-如果你有一些钱,不介意买一本书,那就给Ruby编程Ruby和Metaprogramming一个机会(两者都可以在PragProg购买。

答案 3 :(得分:0)

您可以尝试将哈希构造函数与块一起使用,所以

def foo
  puts "hi"
end

test = Hash.new do |hash, key|
  send(key) if respond_to?(key)
end

test["foo"] # prints "hi", returns nil