我无法弄清楚如何为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)和数百种功能 呼叫周期
答案 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.-您可以查看lambda
,Proc
和Object#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