Ruby: что не так с этой функцией change_keys? - PullRequest
0 голосов
/ 22 февраля 2012
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 ]

3 голосов
/ 22 февраля 2012

Ruby интерпретирует keys[0] и остальные строки 5 как локальные переменные, поскольку он видел 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)
0 голосов
/ 22 февраля 2012

Вы не определили переменную экземпляра с именем 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)

Попробуйте и дайте мне знать.

0 голосов
/ 22 февраля 2012

Атрибуты являются переменными экземпляра, поэтому вы должны ссылаться на keys как @keys везде в вашем методе.

0 голосов
/ 22 февраля 2012

Похоже, вы ожидаете, что keys в вашем методе change_keys будет ссылаться на переменную экземпляра (такую ​​же, как вы явно указали при записи klass.keys = [1,2,3,4,5]), но это не так. Вы хотите @keys вместо.

(Существуют языки программирования, такие как C ++, Smalltalk и Java, в которых имена неукрашенных переменных автоматически используются для ссылки на переменные экземпляра. Ruby не является одним из них.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...