Ruby:这个更改键函数有什么问题?

Ruby:这个更改键函数有什么问题?,ruby,Ruby,这根本不起作用,错误是:nil:NilClass的未定义方法“[]”方法看起来您希望键,在change\u keys方法中,引用实例变量(与您通过编写klass.keys=[1,2,3,4,5]显式设置的变量相同),但实际情况并非如此。您需要的是@键 (有编程语言,如C++和SimultAcess和java,其中未经修饰的变量名自动引用实例变量。露比不是其中之一)。< /P> < P>您没有定义一个名为KEY的实例变量来引用它。我将添加初始化并使用@keys实例变量: class Klass

这根本不起作用,错误是:nil:NilClass的未定义方法“[]”方法看起来您希望
,在
change\u keys
方法中,引用实例变量(与您通过编写
klass.keys=[1,2,3,4,5]
显式设置的变量相同),但实际情况并非如此。您需要的是
@键


(有编程语言,如C++和SimultAcess和java,其中未经修饰的变量名自动引用实例变量。露比不是其中之一)。< /P> < P>您没有定义一个名为KEY的实例变量来引用它。我将添加初始化并使用@keys实例变量:

class Klass
  attr_accessor :keys
  def change_keys(opt)
    if opt == 1
      keys = [keys[0], keys[keys.length - 1]]
    else
      tmp = keys[0]
      keys[0] = keys[keys.length-1]
      keys[keys.length-1] = tmp
    end
    keys
  end
end
klass = Klass.new
klass.keys = [1,2,3,4,5]

# puts klass.change_keys(1)
# puts klass.change_keys(2)

试试看,让我知道。

属性是实例变量,因此您应该在方法中的任何地方将
keys
称为
@keys

Ruby将
keys[0]
和第5行中的其他属性解释为局部变量,因为它看到了
keys=…
。Ruby语法在区分局部变量和没有参数的方法调用时存在歧义,这些参数通过启发式方法消除了歧义。也就是说,如果解析器看到对该标识符的赋值,那么如果不是方法调用,那么它就是一个局部变量

您可以通过引用self.keys来解决此问题。以明确您要使用访问器方法

class Klass
  #attr_accessor :keys
  def initialize(keys)
    @keys = keys
  end

  def change_keys(opt)
    if opt == 1
      @keys = [@keys[0], @keys[@keys.length - 1]]
    else
      tmp = @keys[0]
      @keys[0] = @keys[@keys.length-1]
      @keys[@keys.length-1] = tmp
    end
    @keys
  end
end
klass = Klass.new([1,2,3,4,5])

# puts keys.change_keys(1)
# puts keys.change_keys(2)

a) 考虑到最后两行是注释的,我很确定代码不会显示任何错误b)假设它们不是要注释的:“键”来自哪里?您将变量命名为
klass
,而不是
keys
,我相信我的代码中有一个很大的错误!将keys更改为@keys当然有效,但如果我定义了一个方法:def keys;返回@键;结束?他对Klass#keys=的调用初始化了@keys,所以这不是问题所在。这可以正常工作。这就是attr_访问器所做的。无论是通过attr_访问器还是通过名为keys的方法,您都可以访问instance@keys变量。@是区分变量作用域的ruby方法@@keys是一个类变量,$keys是一个全局变量。如果只是为了初始化,就不允许直接访问实例变量。我不应该在那里更改他的代码。如果不是因为@ecerulm所说的,使用
是可行的<代码>键将调用属性读取器,这实际上是一种常见模式。
class Klass
  attr_accessor :keys
  def change_keys(opt)
    if opt == 1
      self.keys = [keys[0], keys[keys.length - 1]]
    else
      tmp = keys[0]
      keys[0] = keys[keys.length-1]
      keys[keys.length-1] = tmp
    end
    keys
  end
end
klass = Klass.new
klass.keys = [1,2,3,4,5]

puts klass.change_keys(1)
puts klass.change_keys(2)