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

person yoshyosh    schedule 17.04.2011    source источник
comment
Почему вы пытаетесь разделить число в первую очередь?   -  person cHao    schedule 18.04.2011
comment
То, что у вас есть в этом списке с именем DATA, — это числа типа FIXNUM. и нет там никакого сплит-метода!   -  person govi    schedule 18.04.2011
comment
Пожалуйста, опишите, чего вы на самом деле пытаетесь достичь.   -  person Phrogz    schedule 18.04.2011
comment
спасибо, ребята, в следующий раз я обязательно опубликую то, что я пытаюсь сделать, чтобы это было более ясно! Теперь я знаю, что разделение предназначено для строк, а не для целых чисел.   -  person yoshyosh    schedule 18.04.2011


Ответы (3)


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

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

DATA = ['3,4', '5,6', '7,8']
DATA.each do |val|
  vals = line.split ','
  print vals[0] + vals[1], " "
end
person Jon Gauthier    schedule 17.04.2011

Непонятно, что вы пытаетесь сделать. У вас нет «линии», у вас есть элемент из массива, который является целым значением. 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(), каждый объект в системе ответит, но, к счастью, только с ошибкой.

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

person DigitalRoss    schedule 17.04.2011
comment
кое-что из этого вышло у меня из головы, я такой нуб в программировании :(. Но теперь я понимаю, что split - это метод для строк, а не для целых чисел, спасибо! - person yoshyosh; 18.04.2011
comment
Извините, мне позвонили, пока я немного объяснял. Я не уверен, что правильно понял все аспекты этого объяснения; если нет, я надеюсь, что кто-то даст нам более подробную информацию. - person DigitalRoss; 18.04.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
person Phrogz    schedule 18.04.2011
comment
просто работаю с киркой, в конечном итоге это то, чего я пытался достичь, но сначала соединив числа как 34, 56, 78, а затем используя to_i, чтобы заставить их добавить, спасибо за вашу помощь! - person yoshyosh; 18.04.2011
comment
@yoshyosh См. мой обновленный ответ выше, чтобы узнать о гораздо лучшем способе работы с парами целых чисел, чем использование строки, разбиение и синтаксический анализ (принятый в настоящее время ответ). - person Phrogz; 18.04.2011