def track_for stat
# This is a hash with 2 elements of proc
{
symbol: -> { send(stat) },
array: -> { send(stat[0], stat[1]) }
}.freeze[stat.class.name.underscore.to_sym].call
end
冻结[stat.class.name.underscore.to_sym] .call,我不知道这段代码。 []
中代码的功能是什么,以及使用call
方法的原因是什么?谁可以帮助我?非常欣赏它。
答案 0 :(得分:8)
freeze
- 阻止修改哈希(返回冻结的对象)[]
- 访问哈希值stat.class.name.underscore.to_sym
- 我假设这会返回给定对象的类名的小写,蛇案例版本(underscore
不在标准库中,因此我并不完全肯定)call
调用与stat.class.name.underscore.to_sym
键关联的lambda。例如,将['foo', 'bar']
作为参数传递给track_for
将调用send(stat[0], stat[1])
lambda。
答案 1 :(得分:4)
如果我们解开代码,可以将其翻译为:
def track_for stat
case stat
when Symbol
send(stat)
when Array
send(stat[0], stat[1])
end
end
代码中的哈希用于根据变量stat
的类选择正确的行为。
实际上,我在上面的OP代码中看不到翻译代码的任何优点 - 它的可读性较差,并且没有运行时的好处(据我所知)...
答案 2 :(得分:2)
Ruby Freeze方法在不同对象上执行以下操作,基本上是使对象在ruby中保持不变或不变。
str = "this is string"
str.freeze
str.replace("this is new string") #=> FrozenError (can't modify frozen String)
or
str[0] #=> 't'
str[0] = 'X' #=> FrozenError (can't modify frozen String)
但是您可以分配新字符串或更改其引用。一旦引用更改,它就不是冻结(或常量)对象。
str = "this is string"
str.freeze
str.frozen? #=> true
str = "this is new string"
str.frozen? #=> false
arr = ['a', 'b', 'c']
arr.freeze
arr << 'd' #=> FrozenError (can't modify frozen Array)
arr[0] = 'd' #=> FrozenError (can't modify frozen Array)
arr[1].replace('e') #=> ["a", "e", "c"]
arr.frozen? #=> true
arr array被冻结意味着您无法更改阵列。但是数组中的字符串没有冻结。如果执行替换操作 在字符串“ one”上,错误地将其转换为“ e”,当您重新检查(仍然冻结!)数组时,将显示字符串的新内容。
hash = {a: '1', b: '2'}
hash.freeze
hash[:c] = '3' #=> FrozenError (can't modify frozen Hash)
hash.replace({c: '3'}) #=> FrozenError (can't modify frozen Hash)
hash.merge({c: '3'}) #=> return new hash {:a=>"1", :b=>"2", :c=>"3"}
hash.merge!({c: '4'}) #=> FrozenError (can't modify frozen Hash)
hash.frozen? #=> true
hash = {:a=>"1", :b=>"2", :c=>"3"}
hash.frozen? #=> false
因此我们无法修改哈希内容,但可以将其引用为新哈希(就像数组一样)