withCallingHandlers() dan Restart
Gunakan withCallingHandlers() untuk menangani kondisi nonlokal.
withCallingHandlers() dan Restart adalah pelajaran R Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar R Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus R Academy mencakup 4 pelajaran total.
tryCatch vs withCallingHandlers
Perbedaan utamanya: tryCatch() membuat keluar nonlokal — setelah kondisi ditangkap, alur kendali berpindah keluar dari ekspresi dan tidak kembali. withCallingHandlers() mempertahankan tumpukan pemanggilan dan dapat melanjutkan eksekusi setelah penanganan.
# tryCatch: execution does NOT continue after warning
tryCatch({
warning('first')
cat('This line is never reached\n')
}, warning = function(w) cat('tryCatch caught:', w$message, '\n'))withCallingHandlers Mempertahankan Eksekusi
Dengan withCallingHandlers(), penangan dijalankan, tetapi eksekusi berlanjut setelah kondisi diberi sinyal (kecuali penangan itu sendiri menghasilkan error atau memanggil pengaktifan ulang). Tumpukan pemanggilan tidak dibatalkan.
withCallingHandlers({
warning('first warning')
cat('Execution continues here\n')
warning('second warning')
cat('And here too\n')
}, warning = function(w) {
cat('Handler saw:', w$message, '\n')
invokeRestart('muffleWarning')
})Pengaktifan Ulang muffleWarning
Memanggil invokeRestart('muffleWarning') di dalam penangan peringatan mencegah peringatan dicetak oleh penangan bawaan R. Tanpanya, setelah penangan Anda dijalankan, R tetap akan mencetak peringatan melalui mekanisme bawaannya.
# Without muffleWarning: warning still shows after handler
withCallingHandlers({
warning('test')
}, warning = function(w) {
cat('Handler ran\n')
# no muffleWarning: default handler still fires
})Pengaktifan Ulang muffleMessage
Demikian pula, invokeRestart('muffleMessage') di dalam penangan pesan membungkam pesan setelah penangan khusus Anda memprosesnya. Inilah mekanisme di balik suppressMessages().
withCallingHandlers({
message('Progress: 50%')
message('Progress: 100%')
}, message = function(m) {
cat('[LOG]', trimws(m$message), '\n')
invokeRestart('muffleMessage')
})Mencatat Peringatan Tanpa Menghentikan Eksekusi
Salah satu penggunaan praktis withCallingHandlers() adalah mengumpulkan peringatan ke dalam vektor log sambil membiarkan kode selesai. tryCatch() akan berhenti pada peringatan pertama; withCallingHandlers() mengumpulkan semuanya.
warnings_log <- character(0)
result <- withCallingHandlers({
x <- log(-1)
y <- sqrt(-4)
c(x, y)
}, warning = function(w) {
warnings_log <<- c(warnings_log, w$message)
invokeRestart('muffleWarning')
})
cat('Warnings logged:', length(warnings_log), '\n')
cat(warnings_log, sep = '\n')Konsep invokeRestart()
Pengaktifan ulang adalah strategi pemulihan yang telah ditentukan sebelumnya dan dapat ditawarkan oleh kode yang memberi sinyal kondisi. invokeRestart(name) memilih salah satu strategi tersebut. Pengaktifan ulang bawaan mencakup 'muffleWarning' dan 'muffleMessage'; Anda dapat menentukan pengaktifan ulang khusus dengan withRestarts().
# withRestarts() offers named recovery options
divide_safe <- function(x, y) {
withRestarts(
{
if (y == 0) stop('division by zero')
x / y
},
use_zero = function() 0,
use_na = function() NA
)
}
# A handler can pick a restart
withCallingHandlers(
divide_safe(10, 0),
error = function(e) invokeRestart('use_zero')
)Menggabungkan withCallingHandlers dan tryCatch
Anda dapat menumpuk keduanya: gunakan withCallingHandlers() di bagian luar untuk mencatat atau menghitung kondisi, dan tryCatch() di bagian dalam untuk menyediakan nilai pengganti. Penangan bagian luar melihat kondisi tersebut terlebih dahulu.
n_warnings <- 0L
result <- withCallingHandlers(
tryCatch(log(-1), warning = function(w) -999),
warning = function(w) {
n_warnings <<- n_warnings + 1L
cat('Logged warning #', n_warnings, '\n')
}
)
cat('Result:', result, '\n')Kelas Kondisi Khusus
Anda dapat membuat kelas kondisi khusus dengan memanggil structure() pada sebuah daftar dengan kelas c('myError', 'error', 'condition'). Penangan mencocokkan berdasarkan kelas, sehingga kelas khusus memungkinkan Anda menangkap jenis error tertentu tanpa menangkap semua error.
my_error <- function(msg, data = NULL) {
structure(
class = c('my_error', 'error', 'condition'),
list(message = msg, data = data)
)
}
tryCatch(
stop(my_error('custom error', data = 42)),
my_error = function(e) cat('Custom handler, data=', e$data, '\n'),
error = function(e) cat('Generic handler\n')
)Kapan Menggunakan withCallingHandlers
Gunakan withCallingHandlers() saat Anda ingin mengamati atau mencatat kondisi tanpa menghentikan eksekusi. Gunakan tryCatch() saat Anda ingin memulihkan diri dari suatu kondisi dan mengembalikan nilai alternatif. Keduanya menyelesaikan masalah yang berbeda.
# withCallingHandlers: observe all, continue
withCallingHandlers(
for (x in c(4, -1, 9, -4)) cat(suppressWarnings(sqrt(x)), ''),
warning = function(w) cat('[warn]', '')
)
cat('\n')Rangkaian Pemberian Sinyal Kondisi
Saat suatu kondisi diberi sinyal, R menelusuri tumpukan pemanggilan ke atas untuk mencari penangan. Penangan withCallingHandlers() dijalankan dalam konteks dinamis (tumpukan pemanggilan tetap utuh). Penangan tryCatch() dijalankan setelah pembongkaran tumpukan — konteks aslinya sudah tidak ada.
# Demonstrate: withCallingHandlers handler can see full stack
f <- function() {
withCallingHandlers(
g(),
warning = function(w) {
cat('Caught in f, stack length:', sys.nframe(), '\n')
invokeRestart('muffleWarning')
}
)
}
g <- function() warning('from g')
f()Implementasi suppressWarnings()
suppressWarnings(expr) pada dasarnya adalah withCallingHandlers(expr, warning = function(w) invokeRestart('muffleWarning')). Dengan memahaminya, Anda dapat membuat variasi sendiri yang hanya membungkam jenis peringatan tertentu.
# Suppress only NaN warnings, not others
suppress_nan_warn <- function(expr) {
withCallingHandlers(expr, warning = function(w) {
if (grepl('NaN', conditionMessage(w)))
invokeRestart('muffleWarning')
})
}
suppress_nan_warn(log(-1)) # NaN warning suppressed
tryCatch(
suppress_nan_warn(warning('other issue')),
warning = function(w) cat('Other warning kept:', w$message, '\n')
)Pemeriksaan Singkat
Apa perbedaan utama antara withCallingHandlers() dan tryCatch()?
Pengaktifan Ulang: Inti Pembelajaran
Inti pembelajaran tentang withCallingHandlers dan pengaktifan ulang:
withCallingHandlers()= penangan lokal, tumpukan pemanggilan tetap utuh, eksekusi dapat berlanjuttryCatch()= keluar nonlokal, tumpukan dibongkar, dapat mengembalikan nilai alternatifinvokeRestart('muffleWarning')mencegah pencetakan bawaan peringataninvokeRestart('muffleMessage')mencegah pencetakan bawaan pesan- Gunakan
withCallingHandlers()untuk mengumpulkan atau mencatat semua kondisi tanpa berhenti - Kelas kondisi khusus memungkinkan penangkapan jenis error tertentu secara selektif
log_vec <- character(0)
withCallingHandlers({
message('start')
warning('low memory')
message('end')
}, message = function(m) {
log_vec <<- c(log_vec, paste('MSG:', trimws(m$message)))
invokeRestart('muffleMessage')
}, warning = function(w) {
log_vec <<- c(log_vec, paste('WARN:', w$message))
invokeRestart('muffleWarning')
})
cat(log_vec, sep = '\n')Pertanyaan yang Sering Diajukan
Apakah pelajaran “withCallingHandlers() dan Restart” gratis?
Ya — teks lengkap “withCallingHandlers() dan Restart” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus R Academy, upgrade ke CoddyKit PRO. Kursus R Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “withCallingHandlers() dan Restart”?
Gunakan withCallingHandlers() untuk menangani kondisi nonlokal. Kamu berlatih R Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai R Academy?
Tidak diperlukan pengalaman sebelumnya. R Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “withCallingHandlers() dan Restart” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran R Academy ini?
Ya. Setiap pelajaran R Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Error, Peringatan, dan Pesan dalam R
- tryCatch() untuk Pemulihan dari Error
- withCallingHandlers() dan Restart
- Menulis Fungsi Tangguh dengan stop() dan warning()