【问题标题】:Why am I unable to edit the values in this hash?为什么我无法编辑此哈希中的值?
【发布时间】:2019-11-16 14:20:47
【问题描述】:

我正在尝试创建一个名为 $player[:abil_mods] 的新哈希,它基于我的 $player[:abils] 哈希。它应该取每个值,减去 10,除以 2,然后将其分配给新哈希中的相同键。但是,它似乎没有编辑$player[:abil_mods] 中的值。

我的代码:

$player = {
  abils: {str: 20, con: 20, dex: 14, wis: 12, int: 8, cha: 8},
  abil_mods: {}
}

$player[:abil_mods] = $player[:abils].each { |abil, pts| ((pts - 10) / 2).floor }

应该创建以下$player[:abil_mods] 哈希:

abil_mods: {str: 5, con: 5, dex: 2, wis: 1, int: -1, cha: -1}

但它是在创建:

abil_mods: {str: 20, con: 20, dex: 14, wis: 12, int: 8, cha: 8}

【问题讨论】:

  • 使用全局$player 的可能性非常大,这不是正确的做法。大多数情况下,人们在不了解变量作用域时使用全局变量,因为全局变量会绕过作用域问题,但它会为代码中的错误和问题打开一个大洞。我建议您花更多时间了解为什么应该使用它们,为什么不使用它们。

标签: ruby ruby-hash


【解决方案1】:

我很确定 #each 返回它正在操作的哈希值。 (至少它在数组上是这样工作的......)它更多的是关于对每个条目做一些事情,而不是返回那个东西的结果。

你可以试试:

$player[:abil_mods] = $player[:abils].transform_values { |pts| ((pts - 10) / 2).floor }

【讨论】:

    【解决方案2】:

    问题是在行

    $player[:abil_mods] = $player[:abils].each { |abil, pts| ((pts - 10) / 2).floor }
    

    您将Hash#each 方法的返回值self 分配给键:abil_mods 处的哈希$player。在您的情况下,哈希由 $player[:abils] 引用。

    您可以使用Enumerable#map,它返回一个可以轻松转换为哈希的数组:

    $player[:abil_mods] = $player[:abils].map { |k, pts| [k,  ((pts - 10) / 2).floor] }.to_h
    

    【讨论】:

      【解决方案3】:

      只需在此行中使用map 而不是each

      $player[:abil_mods] = $player[:abils].map { |abil, pts| ((pts - 10) / 2).floor }
      

      each 遍历数组但返回原始数组。而map 返回新值。

      顺便说一句:使用全局变量(带有$ 的变量)几乎每次都是一个坏主意。最好使用局部变量的实例。

      【讨论】:

      • 明白了,谢谢。为什么使用全局变量是个坏主意?我只听说过使用它们不是很 Ruby。
      • 全局变量的问题在于,它们不仅在程序代码的任何地方都可见,而且还可以在应用程序的任何地方进行更改。这会使跟踪错误变得困难。我认为这样的全局变量和全局状态是代码异味。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-06
      • 2011-12-27
      • 2015-11-02
      • 2014-09-08
      • 2012-12-30
      • 2015-01-02
      • 2019-10-03
      相关资源
      最近更新 更多