哈希键作为类中的访问器
我正在开发一个读取一些传感器信息并将其作为哈希值返回的类。我想使用哈希键作为访问器,但我没有太多运气让它工作。到目前为止,以下是我的代码的相关部分:
我已经尝试使用 method_missing 和使用 :define_method
方法。
attr_reader :sensor_hash
def method_missing(name, *args, &blk)
if args.empty? && blk.nil? && @sensor_hash.has_key?(name.to_s)
@sensor_hash[name.to_s]
else
super
end
end
def sensor(*sensor_to_return)
sensor_output = run_command(this_method_name)
sensor_output = sensor_output.split("\n")
sensor_output.map! { |line| line.downcase! }
unless sensor_to_return.empty?
sensor_to_return = sensor_to_return.to_s.downcase
sensor_output = sensor_output.grep(/^#{sensor_to_return}\s/)
end
@sensor_hash = Hash.new
sensor_output.each { |stat| @sensor_hash[stat.split(/\s+\|\s?/)[0].gsub(' ','_').to_sym] = stat.split(/\s?\|\s?/)[1..-1].each { |v| v.strip! } }
@sensor_hash.each do |k,v|
puts v.join("\t")
self.class.send :define_method, k { v.join("\t") }
end
return @sensor_hash
返回的数据是以传感器名称作为键的哈希值,值是返回的所有其他内容的数组。我的目标是能够调用 Class.sensor.sensor_name 并获取 Class.sensor[:sensor_name] 的输出。目前,我所能得到的只是一个未定义的方法错误。有人知道我在这里做错了什么吗?
I'm working on a class that reads some sensor information and returns it as a hash. I would like to use the hash keys as accessors, but I'm not having much luck getting it work. Here are the relevant parts of my code so far:
I've tried it both with method_missing and by using the :define_method
method.
attr_reader :sensor_hash
def method_missing(name, *args, &blk)
if args.empty? && blk.nil? && @sensor_hash.has_key?(name.to_s)
@sensor_hash[name.to_s]
else
super
end
end
def sensor(*sensor_to_return)
sensor_output = run_command(this_method_name)
sensor_output = sensor_output.split("\n")
sensor_output.map! { |line| line.downcase! }
unless sensor_to_return.empty?
sensor_to_return = sensor_to_return.to_s.downcase
sensor_output = sensor_output.grep(/^#{sensor_to_return}\s/)
end
@sensor_hash = Hash.new
sensor_output.each { |stat| @sensor_hash[stat.split(/\s+\|\s?/)[0].gsub(' ','_').to_sym] = stat.split(/\s?\|\s?/)[1..-1].each { |v| v.strip! } }
@sensor_hash.each do |k,v|
puts v.join("\t")
self.class.send :define_method, k { v.join("\t") }
end
return @sensor_hash
The data returned is a hash with the sensor name as the key and and the value is an array of everything else returned. My goal is to be able to call Class.sensor.sensor_name
and get the output of Class.sensor[:sensor_name]
. Currently, all I'm able to get is an undefined method error. Anybody have any idea what I'm doing wrong here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
也许 OpenStruct 可以满足您的需求。来自 doc :“它就像一个散列,以不同的方式事实上,它是用哈希值实现的,你可以用一个哈希值来初始化它。”
Maybe OpenStruct does what you want. From the doc :"It is like a hash with a different way to access the data. In fact, it is implemented with a hash, and you can initialize it with one."
只是一个简单的例子。你有什么理由不对你的哈希值进行猴子补丁吗?
Just a quick example. Do you have any reasons to not monkey-patch your Hash?
您可以使用缺少方法的包装类,这样您就不必猴子修补
Hash
。或者,如果您正在使用 Rails,它有一些很好的内置对象委托与
SimpleDelegator
。这将允许您在哈希值以及其中的任何嵌套哈希值上定义访问器。这在实例化时的性能会比
method_missing
低,因为它必须在创建后立即在您的委托对象上递归运行。但是,它绝对比method_missing
更安全,并且比猴子修补Hash
类更安全。当然,安全性与您的目标相关,如果这就是您的应用程序所做的一切,那么猴子补丁就可以了。如果您想要没有轨道的递归嵌套访问器,您可以结合上述内容执行类似的操作...
但是到那时您会变得非常疯狂,并且可能值得重新评估您的解决方案以支持更面向对象的解决方案。如果我在代码审查中看到其中任何一个,它肯定会引发危险信号。 ;)
You could use a wrapper class with method missing so you don't have to monkey patch
Hash
.Or, if you are working with Rails it has some nice built in object delegation with
SimpleDelegator
. That would allow you to define accessors on your hash as well as any nested hashes within it.This would be less performant at instantiation than
method_missing
, because it has to run recursively over your delegatee object as soon as it's created. However, it's definitely safer thanmethod_missing
, and certainly way safer than monkey patching yourHash
class. Of course, safety is relative to your goals, If it's all your application does then monkey patch away.And if you want the recursive, nested accessors without rails you could do something like this with a combination of the above...
But at that point you're getting pretty crazy and it's probably worth reevaluating your solution in favor of something more Object Oriented. If I saw any of these in a code review it would definitely throw up a red flag. ;)