Ruby:这个change_keys函数有什么问题?

时间:2012-02-21 22:19:05

标签: ruby

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)

这根本不起作用,错误说:nil的未定义方法'[]'方法:NilClass

4 个答案:

答案 0 :(得分:3)

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

您可以通过引用self.keys来解决此问题。明确表示您要使用存取方法。

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)

答案 1 :(得分:-1)

看起来你期望在keys方法中change_keys引用一个实例变量(与你通过编写klass.keys = [1,2,3,4,5]明确设置的那个相同),但它没有。您想要@keys

(有一些编程语言,比如C ++和Smalltalk和Java,其中自动采用未加修饰的变量名称来引用实例变量.Ruby不是其中之一。)

答案 2 :(得分:-1)

您没有定义名为keys的实例变量来引用它。我会添加初始化并使用@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)

尝试一下,让我知道。

答案 3 :(得分:-1)

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