Ruby: закрытый метод для 3:Fixnum
Я пытаюсь узнать нюансы этой простой функции, но не уверен, что мне нужно сделать, чтобы исправить эту ошибку 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 ответа
Вы вызываете метод split
на числовом объекте - этот метод существует в String
класс, но не в Fixnum
,
Я думаю, что вы пытаетесь сделать это:
DATA = ['3,4', '5,6', '7,8']
DATA.each do |val|
vals = line.split ','
print vals[0] + vals[1], " "
end
Непонятно, что вы пытаетесь сделать. У вас нет "строки", у вас есть элемент из массива, который является целочисленным значением. 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 каждого экземпляра объекта.
Угадай, что ты действительно хочешь:
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