Ruby冻结方法

时间:2014-12-27 03:16:17

标签: ruby call freeze

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方法的原因是什么?谁可以帮助我?非常欣赏它。

3 个答案:

答案 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中保持不变或不变。

  1. 字符串
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

  1. 数组:-
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”,当您重新检查(仍然冻结!)数组时,将显示字符串的新内容。

  1. 哈希
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

因此我们无法修改哈希内容,但可以将其引用为新哈希(就像数组一样)