【问题标题】:Ruby freeze method红宝石冻结法
【发布时间】:2015-02-24 04:11:03
【问题描述】:
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

freeze[stat.class.name.underscore.to_sym].call ,我不知道这段代码。 []里面的代码的作用是什么,为什么要用call方法?谁能帮助我?非常感谢。

【问题讨论】:

    标签: ruby call freeze


    【解决方案1】:

    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 数组被冻结意味着您无法更改数组。但是数组中的字符串并没有被冻结。如果您执行替换操作 在字符串“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
    
    

    所以我们不能修改哈希内容但我们可以将它引用到新的哈希(就像数组一样)

    【讨论】:

      【解决方案2】:

      如果我们解开它可以翻译成的代码:

      def track_for stat
        case stat
          when Symbol
            send(stat)
          when Array
            send(stat[0], stat[1]) 
        end
      end
      

      代码中的哈希用于根据变量stat的类选择正确的行为。

      实际上,我没有看到上面的 OP 代码比翻译后的代码有任何优点 - 它的可读性较差并且没有运行时优势(据我所知)...

      【讨论】:

      • 好吧,有人可能会说 OP 代码的命令性和声明性更少。
      【解决方案3】:
      • 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 { send *stat } end `` 代替吗?对不起格式。我不知道如何在 cmets 中插入代码
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-10
      相关资源
      最近更新 更多