Почему «получает» Ruby включает закрывающую новую строку?

Мне никогда не нужна конечная новая строка, которую я получаю от gets. Половину времени я забываю chomp об этом, и это заноза в сердце....

Почему это там?


person steenslag    schedule 21.06.2011    source источник
comment
Деревообрабатывающая поговорка: из доски всегда можно напилить больше дров, но обратно не вернешь.   -  person DGM    schedule 22.06.2011
comment
@DGM Вы всегда можете добавить \n.   -  person sawa    schedule 22.06.2011
comment
@sawa: Если ты уверен, что там был один для начала.   -  person Andrew Grimm    schedule 22.06.2011
comment
@Andrew Единственный случай, когда вы его не получили, - это когда вы достигли EOF. Но будет ли это иметь значение?   -  person sawa    schedule 22.06.2011
comment
gets — это стандартный метод во многих языках, уходящий своими корнями в C. Его поведение такое же, как и в C, что, вероятно, связано с согласованностью. Я сомневаюсь, что это изменится, поэтому вы, вероятно, захотите привыкнуть либо к автоматическому добавлению chomp, либо уделять больше внимания нужному вам типу данных и добавлять chomp только при необходимости. Это просто одна из тех задач в программировании, которым мы учимся.   -  person the Tin Man    schedule 29.12.2013


Ответы (4)


Как и puts (звучит похоже), он предназначен для работы со строками с использованием символа \n.

gets принимает необязательный аргумент, который используется для «разделения» ввода (или «просто чтения до его поступления»). По умолчанию используется специальная глобальная переменная $/, которая по умолчанию содержит \n.

gets — довольно общий метод для чтения потоков и включает этот разделитель. Если бы он этого не делал, части содержимого потока были бы потеряны.

person J-_-L    schedule 21.06.2011

var = gets.chomp 

Это помещает все это в одну строку для вас.

person Ben Garvey    schedule 07.01.2013
comment
Этот ответ вообще не касается вопроса. Интересно, почему за него так много голосов. - person undur_gongor; 11.09.2015

Если вы посмотрите на документацию IO#gets, вы заметите, что метод принимает необязательный параметр sep, который по умолчанию равен $/ (разделитель входных записей). Вы можете разделить ввод на другие вещи, кроме новых строк, например. параграфы ("разделитель нулевой длины считывает ввод по абзацу за раз (два последовательных символа новой строки во входных отдельных абзацах)"):

>> gets('')
dsfasdf
fasfds


dsafadsf    #=> "dsfasdf\nfasfds\n\n"
person Michael Kohl    schedule 21.06.2011
comment
Тем не менее, возникает вопрос, почему он должен захватывать и возвращать разделитель — "1,2,3".split(',') не возвращает запятые. Я бы сказал (как и в своем ответе), что причина несоответствия заключается в том, что нет никакой дополнительной работы, чтобы убрать запятые из результата для split, но gets должен буферизовать разделитель записей, прежде чем он сможет заметить, что он пришел вдоль. - person Coderer; 22.06.2011
comment
Почему он должен снимать сепаратор? IO#gets используется и в других контекстах, в некоторых из которых удаление разделителя может показаться не таким естественным, как при непосредственном запросе пользовательского ввода. - person Michael Kohl; 22.06.2011

С точки зрения производительности лучшим вопросом было бы «почему я должен избавиться от него?». Это не большая стоимость, но под капотом вы должны заплатить за то, чтобы перегрызть возвращаемую строку. Хотя у вас, возможно, никогда не было случая, когда вам это нужно, у вас наверняка было много случаев, когда вам было все равно -- gets s; puts stuff() if s =~ /y/i и т. д. В этих случаях вы увидите ( крошечный, крошечный) улучшение производительности за счет отсутствия пережевывания.

person Coderer    schedule 21.06.2011
comment
Я не думаю, что это все. Ruby не разработан как быстрый язык, и нет никакой выгоды, если всем все равно придется грызть строку. - person steenslag; 22.06.2011
comment
Тот факт, что Ruby чрезвычайно выразителен, не означает, что вы не можете учитывать скорость. И, как я уже сказал, перевод строки никому не нужен != все должны жевать. - person Coderer; 22.06.2011