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
方法?谁可以帮助我?非常欣赏它。
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。
如果我们解开代码,它可以转换为:
def track_for stat
case stat
when Symbol
send(stat)
when Array
send(stat[0], stat[1])
end
end
代码中的哈希用于根据变量stat
的类选择正确的行为。
实际上,我在上面的OP代码中看不到翻译代码的任何优点 - 它不太可读,没有运行时的好处(据我所知)...
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数组已冻结意味着您无法更改数组。但是数组中的字符串不会被冻结。如果对字符串“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
所以我们不能修改哈希内容,但我们可以将它引用到新哈希(就像数组一样)