hash排序 - ruby hash遍历
我如何调用一个哈希值的方法? (5)
以前,我问过一个聪明的方法来执行一个给定条件的方法:“ 一个聪明的方法来执行一个条件的函数 。
解决方案和响应时间非常棒,但是实施起来,哈希算法很快就会变得很难看。 所以我开始尝试。
以下代码工作:
def a()
puts "hello world"
end
some_hash = { 0 => a() }
some_hash[0]
但是,如果我把它包装在一个班,它停止工作:
class A
@a = { 0 => a()}
def a()
puts "hello world"
end
def b()
@a[0]
end
end
d = A.new()
d.b()
我不明白为什么它应该停止工作,任何人都可以建议如何使其工作?
该代码不起作用。 它在执行时被添加到散列中,而不是从散列中检索(在irb中尝试)。
它在类中不起作用,因为在类上没有定义方法(最终在实例上定义了方法a
。
尝试实际使用类似lambda的
{0 => lambda { puts "hello world" }}
代替
那么,你的类的第一行调用一个不存在的方法。 在整个类被加载后,它将不会存在,因为这将是对类方法的调用,而且只定义了实例方法。
另请注意,{0 => a()}将调用方法a(),而不是创建对方法a()的引用。 如果你想在那里放置一个函数,直到后来才被评估,你就必须使用某种类型的Lambda。
如果你真的想要这样的事情,为什么不把所有的方法都包装在类中呢?
# a container to store all your methods you want to use a hash to access
class MethodHash
alias [] send
def one
puts "I'm one"
end
def two
puts "I'm two"
end
end
x = MethodHash.new
x[:one] # prints "I'm one"
x.two # prints "I'm one"
或者,使用你的例子:
# a general purpose object that transforms a hash into calls on methods of some given object
class DelegateHash
def initialize(target, method_hash)
@target = target
@method_hash = method_hash.dup
end
def [](k)
@target.send(@method_hash[k])
end
end
class A
def initialize
@a = DelegateHash.new(self, { 0 => :a })
end
def a()
puts "hello world"
end
def b()
@a[0]
end
end
x = A.new
x.a #=> prints "hello world"
x.b #=> prints "hello world"
你做的另一个基本的错误是,你在任何实例方法之外初始化了@a
- 只是在A
的定义之内。 这是一个很大的时间不,不,因为它不工作。 请记住,在ruby中,一切都是一个对象,包括类, @
前缀表示任何对象当前自己的实例变量。 在实例方法定义中, self
是类的一个实例。 但除此之外,就在类定义内部, self
就是类对象 - 所以你为类对象A
定义了一个名为@a
的实例变量, A
的实例都不能直接获取。
Ruby确实有这种行为的原因(如果你知道自己在做什么,类实例变量可以非常方便),但这是一种更先进的技术。
总之,只需要初始化initialize
方法中的实例变量。
a = - >(string =“没有字符串通过”)做
放入字符串
结束
some_hash = {0 => a}
some_hash [0] .call(“Hello World”)
some_hash [0] []
我在Ruby中使用回调相当新颖,这就是我使用一个例子向自己解释的:
require 'logger'
log = Logger.new('/var/tmp/log.out')
def callit(severity, msg, myproc)
myproc.call(sev, msg)
end
lookup_severity = {}
lookup_severity['info'] = Proc.new { |x| log.info(x) }
lookup_severity['debug'] = Proc.new { |x| log.debug(x) }
logit = Proc.new { |x,y| lookup_sev[x].call(y) }
callit('info', "check4", logit)
callit('debug', "check5", logit)