Ruby冻结方法

问题描述 投票:4回答:3
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方法?谁可以帮助我?非常欣赏它。

ruby call freeze
3个回答
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。


4
投票

如果我们解开代码,它可以转换为:

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

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

实际上,我在上面的OP代码中看不到翻译代码的任何优点 - 它不太可读,没有运行时的好处(据我所知)...


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

  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

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

© www.soinside.com 2019 - 2024. All rights reserved.