TL; DR
Ви повинні використовувати, cat()
створюючи print.*()
функції для об'єктів S3. Для всього іншого слід використовувати, message()
якщо стан програми не є проблематичним. наприклад, погана помилка, що підлягає відновленню, дає warning()
проти використання помилка зупинки використання stop()
.
Мета
Мета цього допису - надати відгук про різні варіанти виводу, до яких має доступ розробник пакунків, і про те, як слід структурувати вихід, який потенційно може бути на новому об'єкті або базуватися на рядках.
R Огляд вихідних даних
Традиційними функціями виводу є:
print()
cat()
message()
warning()
stop()
Тепер перші дві функції ( print()
і cat()
) надсилають свої вихідні дані до stdout
або стандартного виводу. Три останні функції ( message()
,, warning()
і stop()
) надсилають свої вихідні дані stderr
або стандартну помилку. Тобто результат, виведений з команди типу lm()
, надсилається в один файл, а вивід помилки - якщо він існує - надсилається в абсолютно окремий файл. Це особливо важливо для взаємодії з користувачем, оскільки тоді діагностика не заповнює результати результатів у файлах журналів, а помилки доступні для швидкого пошуку.
Проектування для користувачів та зовнішніх пакетів
Тепер вищезазначене оформлено більше у спосіб миттєвого введення-виведення, і не обов’язково для набору кадрів, що відповідає користувачеві. Отже, давайте подамо мотивацію для цього в контексті повсякденного користувача R. Зокрема, використовуючи 3-5 або stderr
функції, їх вихід можна придушити, не заважаючи тексту консолі за допомогою sink()
або capture.output()
. Придушення зазвичай приходить у вигляді suppressWarnings()
, suppressMessages()
, suppressPackageStartupMessages()
і так далі. Таким чином, користувачі стикаються лише з результатами, які стикаються з результатами. Це особливо важливо, якщо ви плануєте дозволити користувачам гнучко вимикати текстовий вихід при створенні динамічних документів за допомогою в'язального пристрою , rmarkdown або Sweave .
Зокрема, knitr
пропонує варіанти порцій , наприклад error = F
, message = F
і warning = F
. Це дозволяє зменшити текст, що супроводжує команду в документі. Крім того, це запобігає необхідності використання results = "hide"
опції, яка відключала б усі вихідні дані.
Особливості виробництва
print ()
До перших, у нас є дідок , але хороший, print()
. Ця функція має суттєві обмеження. Однією з них є відсутність вбудованої конкатенації термінів. Другий, і, мабуть, більш суворий, полягає в тому, що перед кожним результатом передують [x]
цитати навколо фактичного змісту. У x
цьому випадку посилається на номер елемента, який друкується. Це корисно для налагодження, але поза цим воно не служить жодним цілям.
напр
print("Hello!")
[1] "Hello!"
Для конкатенації ми покладаємось на paste()
функцію, яка працює синхронно з print()
:
print(paste("Hello","World!"))
[1] "Hello World!"
В якості альтернативи можна використовувати paste0(...)
функцію замість, paste(...)
щоб уникнути використання за промовчанням spaceміж елементами, керованими параметром paste()
' sep = " "
. (він же конкатенація без пробілів)
напр
print(paste0("Hello","World!"))
[1] "HelloWorld!"
print(paste("Hello","World!", sep = ""))
[1] "HelloWorld!"
кішка ()
З іншого боку, cat()
розглядаються всі ці зауваження. Найголовніше, що sep=" "
параметр paste()
функціональності вбудований в те, що можна пропустити написання paste()
всередині cat()
. Однак cat()
єдиним недоліком функції є те, що вам потрібно примусити нові рядки за допомогою \n
доданого в кінці або fill = TRUE
(використовує ширину друку за замовчуванням).
напр
cat("Hello!\n")
Hello!
cat("Hello","World!\n")
Hello World!
cat("Hello","World!\n", sep = "")
HelloWorld!
Саме з цієї причини вам слід використовувати cat()
при розробці print.*()
методу S3.
повідомлення()
message()
Функція один крок краще , ніж навіть cat()
! Причина, чому результат виводиться, відрізняється від традиційного звичайного тексту, оскільки спрямовується на stderr
замість stdout
. Наприклад, вони змінили колір із стандартного чорного на червоний, щоб привернути увагу користувачів.
Крім того, у вас є вбудована paste0()
функціональність.
message("Hello ","World!")
"Hello World!"
Більше того, message()
забезпечує стан помилок, з яким можна використовуватиtryCatch()
напр
tryCatch(message("hello\n"), message=function(e){cat("goodbye\n")})
goodbye
увага()
warning()
Функція не те , щоб використовувати випадково. Функція попередження відрізняється від функції повідомлення насамперед тим, що перед нею є префікс ( "Warning message:"
), і її стан вважається проблематичним.
Різне: випадкове використання функції може ненавмисно викликати розлад серця під час спроби завантажити пакунок у CRAN через те, що перевірки прикладів та попередження зазвичай трактуються як "помилки".
Стоп()
І останнє, але не менш важливе, ми маємо stop()
. Це виводить попередження на наступний рівень, повністю вбиваючи завдання і повертаючи контроль назад користувачеві. Крім того, він має найсерйозніший префікс із "Error:"
додаванням терміна .
message()
також сигналізує про "повідомлення", саме це іsuppressMessages()
фіксує.suppressMessages()
не придушуйте вихід чистого stderr, наприклад,suppressMessages(cat("hello\n", file=stderr()))
все ще відображаєтьсяhello
в консолі.