我有一个可以解析不同类型消息的类,我想要做的是创建一个散列,它将使用msg类型id作为键,使用不同的实例方法作为值。
如下所示:
class Parser
def initialize(msg_id)
@my_methods = {1 => method_1, 2 => method_2, 3 => method_3}
@my_methods[msg_id]()
end
def method_1
end
def method_2
end
def method_3
end end我知道这是可能的,但我不确定该怎么做。我尝试使用self.method(:method_1)作为一个值,但是我得到了一个错误,告诉我没有定义method_1。
谢谢
发布于 2016-10-19 16:35:52
修复代码的最简单可能的更改如下所示:
class Parser
def initialize(msg_id)
@my_methods = { 1 => method(:method_1), 2 => method(:method_2), 3 => method(:method_3) }
@my_methods[msg_id].()
end
def method_1; end
def method_2; end
def method_3; end
end例如,使用Object#method方法获取Method对象,并使用Method#call方法执行该对象。
然而,我们可以做一些改进。首先,您的Hash将Integer与值关联起来。但是有一种更好的数据结构已经做到了这一点:Array。(注意:如果您的消息if不是按顺序分配的,那么Hash可能是正确的选择,但是从您的示例看,它们只是从1开始计数的Integer。)
其次,对Parser#initialize方法中的方法进行硬编码可能不是一个好主意。应该有协议的声明性描述,即消息ID及其相应的方法名称。
class Parser
# this will make your message IDs start at 0, though
PROTOCOL_MAPPING = [:method_1, :method_2, :method_3].freeze
def initialize(msg_id)
@my_methods = PROTOCOL_MAPPING.map(&method(:method))
@my_methods[msg_id].()
end
def method_1; end
def method_2; end
def method_3; end
end另一种可能是这样的:
class Parser
PROTOCOL_MAPPING = []
private_class_method def self.parser(name)
PROTOCOL_MAPPING << name
end
def initialize(msg_id)
@my_methods = PROTOCOL_MAPPING.map(&method(:method))
@my_methods[msg_id].()
end
parser def method_1; end
parser def method_2; end
parser def method_3; end
end或者是这样的:
class Parser
PROTOCOL_MAPPING = {}
private_class_method def self.parser(msg_id, name)
PROTOCOL_MAPPING[msg_id] = name
end
def initialize(msg_id)
@my_methods = PROTOCOL_MAPPING.map {|msg_id, name| [msg_id, method(name)] }.to_h.freeze
@my_methods[msg_id].()
end
parser 1, def method_1; end
parser 2, def method_2; end
parser 3, def method_3; end
endhttps://stackoverflow.com/questions/40119666
复制相似问题