Ruby: закрытый метод для 3: Fixnum - PullRequest
2 голосов
/ 18 апреля 2011

Я пытаюсь узнать нюансы этой простой функции, но не уверен, что мне нужно сделать, чтобы исправить эту ошибку NoMethodError.Как сделать разделение публичным, а не частным?Устранит ли это проблему?

Вот мой код:

DATA = [3, 4, 5, 6, 7, 8]
DATA.each do |line|
vals = line.split
print vals[0] + vals[1], " "
end

Вот сообщение об ошибке, которое я получаю при запуске в IRB:

NoMethodError: private method `split' called for 3:Fixnum

Ответы [ 3 ]

4 голосов
/ 18 апреля 2011

Непонятно, что вы пытаетесь сделать. У вас нет «строки», у вас есть элемент из Array , который является значением Integer . Split - это метод, определенный для String.

DATA = [3, 4, 5, 6, 7, 8]
DATA.each do |val|
  print val
end

Теперь причина, по которой вы получаете это запутанное сообщение об ошибке, немного интересна. Как это бывает, существует Kernel#split, который допускает Perl-подобную краткость для сценариев. Он разбивает глобальную переменную $_, которая содержит последний результат из gets.

>> gets
how now brown cow
=> "how now brown cow\n"
>> split ' '
=> ["how", "now", "brown", "cow"]
>> puts $_
how now brown cow

Но смешивание с Object, так что оно доступно на уровне сценария, оставляет проблему в том, что у каждого когда-либо созданного класса возникает метод #split.

Если вы запустите простой старый split (), каждый объект в системе будет реагировать, но, к счастью, только с ошибкой.

Делая это приватным методом, он доступен на верхнем уровне для сценариев (потому что «Объект» открыт или что-то в этом роде), но не является частью API каждого экземпляра объекта.

1 голос
/ 18 апреля 2011

Вы вызываете метод split для числового объекта - этот метод существует в классе String, но не в Fixnum.

Я думаю, что вы пытаетесь сделать это:

DATA = ['3,4', '5,6', '7,8']
DATA.each do |val|
  vals = line.split ','
  print vals[0] + vals[1], " "
end
0 голосов
/ 18 апреля 2011

Угадайте, что вы действительно хотите:

DATA = 3..8
DATA.each_cons(2) do |a,b|
  puts "#{a} + #{b} = #{a+b}"
end
#=> 3 + 4 = 7
#=> 4 + 5 = 9
#=> 5 + 6 = 11
#=> 6 + 7 = 13
#=> 7 + 8 = 15

Редактировать : основано на желании оперировать последовательными парами:

DATA = 3..8    # or DATA = [3,4,5,6,7,8]
DATA.each_slice(2) do |a,b|
  puts "#{a} + #{b} = #{a+b}"
end
#=> 3 + 4 = 7
#=> 5 + 6 = 11
#=> 7 + 8 = 15
...