我正在尝试(实际上成功了,但我不明白它是如何工作的)在我的模型中为哈希写一个自定义方法(我正在Ruby on Rails 6上工作)。
我的哈希值是这样的
my_hash = {
[['name_1', 'slug_1']=>value_1],
[['name_2', 'slug_2']=>value_2],
[['name_1', 'slug_1']=>value_3],
[['name_2', 'slug_2']=>value_4]
}
基本上就是数组的哈希。您注意到"键"是重复多次的数组,但具有不同的值。我想要实现的是编写一个自定义方法来"join"。所有的键都在一个键中,它将有一个赋值数组,所以基本上我应该能够得到:
my_hash = {
['name_1', 'slug_1']=>"values": [value_1, value_3],
['name_2', 'slug_2']=>"values": [value_2, value_4]
}
,我有这段代码,我使用很多次:
my_hash.inject({}) do |hash, record|
# each record has the following format => [["unit_name", "axis.slug"]=>average_value(float)]
keys, value = record
# now keys has ["unit_name", "axis.slug"] and values equals average_value
hash[keys.first] ||= {}
hash[keys.first][keys.last] = value.to_f
hash
end
自从我使用这个很多次,我想编写一个定制的方法,所以我做了:
def format_hash_data my_hash
my_hash.inject({}) do |hash, record|
# each record has the following format => [["unit_name", "axis.slug"]=>average_value(float)]
keys, value = record
# now keys has ["unit_name", "axis.slug"] and values equals average_value
hash[keys.first] ||= {}
hash[keys.first][keys.last] = value.to_f
hash
end
end
和使用它:my_hash = format_hash_data(my_hash)
没有成功(它抛出一个错误说"format_hash_data"不是一个有效的方法类)。
所以我摆弄了一下,在方法名中加入了'self',留下了:
def self.format_hash_data my_hash
my_hash.inject({}) do |hash, record|
# each record has the following format => [["unit_name", "axis.slug"]=>average_value(float)]
keys, value = record
# now keys has ["unit_name", "axis.slug"] and values equals average_value
hash[keys.first] ||= {}
hash[keys.first][keys.last] = value.to_f
hash
end
end
令我惊讶的是,当使用my_hash = format_hash_data(my_hash)
时,它可以完美地工作。我真的不明白为什么添加"self"使我的代码工作,也许有人可以透露一些光?我尝试使用send()
或instance_eval
之类的东西首先,只是将代码块发送到实际哈希作为方法(如my_hash.instance_eval(my_method)
),但我无法让它工作。
我很抱歉这么长时间的解释,我希望我说得足够清楚,这样你们中的任何一个有同样困境的人都能理解。提前谢谢。
在方法名前加上self.
使其成为类方法而不是实例方法。如果你不确定它们之间的区别,你应该去查一下,因为这是正确定义和使用类和方法的基础。
作为一个类方法,你可以这样使用它:
my_hash = MyHash.format_hash_data(my_hash)
或者,如果您在类的作用域内,则只需使用my_hash = format_hash_data(my_hash)
,这就是为什么在您的情况下使用前置self.
(类方法定义)。
如果你想把它定义为一个实例方法(一个为实例定义的方法),你可以这样使用它:
my_hash = my_hash.format_hash_data
定义将使用实例的隐式self
:
def format_hash_data
self.inject({}) do |hash, record|
# each record has the following format => [["unit_name", "axis.slug"]=>average_value(float)]
keys, value = record
# now keys has ["unit_name", "axis.slug"] and values equals average_value
hash[keys.first] ||= {}
hash[keys.first][keys.last] = value.to_f
hash
end
end