【问题标题】:Why am I getting a "no method" error for a simple matrix add operation in Ruby? Many essentially identical lines in my other programs为什么我在 Ruby 中进行简单的矩阵添加操作会出现“无方法”错误?我的其他程序中有许多基本相同的行
【发布时间】:2020-04-20 13:56:57
【问题描述】:

这是错误声明:

EvoWithout.rb:53:in `block (2 levels) in ': undefined method `+' for nil:NilClass (NoMethodError)

这是第 53 行:

if behavior[i,0] > Thrsh && s == 0 then animal[i,0]+= 5 end

以下是相关代码:

situation= Matrix[ [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
                   [1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1],
                   [1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1],
                   [1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1],
                   [1,0,0,1,1,0,1,0,1,0,1,0,1,0,0,1] ]
# Build brain with $Behavmax rows of 0,1's
brain = Matrix.build(10,16) { 1 }
for i in (0..$Behavmax)
    for j in (0..$Stimmax)
        if rand(4) < 1.1 then brain[i,j] = 0 end
    end # j
end #i
stimulus=Matrix.column_vector([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])
behavior=Matrix.row_vector([0,0,0,0,0,0,0,0,0,0])
animal=Matrix.row_vector([20,20,20,20,20,20,20,20,20,20]) # to hold value of fitness
# BEGIN MAIN PROGRAM
# Noise=20
# Go through once presenting 1 situation after another
for s in (0..4)
    for j in (0..$Stimmax)
        stimulus[j,0] = situation[s,j]
    end # for j
    # GENERATE BEHAVIOR
    behavior=brain*stimulus 
     for i in (0..$Behavmax) #fire iff stimulus pattern matches detector
        if behavior[i,0] > Thrsh && s == 0 then animal[i,0]+= 5 end
        #if behavior[i,0] > Thrsh && s != 0 then  print "Behavior#{i}=#{behavior[i,0]} and s=#{s}   " end
     end # for i
    puts
end # for s

【问题讨论】:

  • animal 矩阵由一行组成,所以animal[1, 0] == nil,这可能就是它发生的原因。
  • 不,不是这样。将其更改为animal[1] 会出现此错误:lib/ruby/2.6.0/matrix.rb:299:in `[]': wrong number of arguments (given 1, expected 2) (ArgumentError)
  • 这不是重点。 animal[0, 0] 返回20,就像animal[0, 1] 等一样。看起来你应该有behavior[0, i]animal[0, i] 而不是behavior[i, 0]animal[i, 0]
  • 好的,可以。但你会注意到我使用behavior[i,0] 并且它有效。确实,我复制行为来制造动物。所以没有明显的原因为什么动物不起作用。但我会尝试
  • 这并不神秘。 animalbehavior 矩阵每个只包含一行,所以如果你想迭代它的值,你需要迭代列,而不是行。 animal[i, 0] 遍历行。 animal[0, i] 遍历列。

标签: ruby matrix methods undefined


【解决方案1】:

要学习的一项重要技能是阅读错误消息和警告。在你的标题中,你问:

为什么在 Ruby 中进行简单的矩阵加法运算时会出现“无方法”错误?

但是,这不是错误消息所说的!

不会得到一个NoMethodError 用于矩阵加法运算 (Matrix#+)。如果是,错误消息会显示如下内容:

EvoWithout.rb:53:in `block (2 levels) in ': undefined method `+' for animal:Matrix (NoMethodError)

请注意,错误消息会显示(bold强调我的)“animal:Matrix的未定义方法`+'”(这是错误的,因为Matrix#+存在)。但是,这不是您的错误消息所说的。您的错误消息显示(粗体强调我的):

nil:NilClass

的未定义方法 `+'

这是正确的,因为NilClass 实际上没有 有一个+ 方法,它的超类ObjectKernelBasicObject 也没有。

所以,你找错地方了:你的问题不在于矩阵相加操作,你的问题是你的矩阵 index 操作返回nil

原因很简单:animal 矩阵仅包含一行,但您正在迭代 $Behavmax + 1 行。因此,一旦$Behavmax 大于零,您将索引到不存在的animal 的第二行。因此,它会返回nil,并且您的添加将失败。

请记住,a ω= b 对于任何运算符 ω 和任意表达式 ab 等价于 a = a ω ba 只计算一次,所以

animal[i,0]+= 5

大致相当于:

__temp__ = animal[i, 0]
animal[i, 0] = __temp__ + 5

如果i 不是0,则__temp__ 将是nil,因为animal 中只有一行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-16
    • 1970-01-01
    • 2013-09-15
    • 1970-01-01
    相关资源
    最近更新 更多