Melindungi state
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan R di Coddy. Pelajaran 20 dari 57.
Setter adalah satu-satunya tempat nilai dapat berubah, jadi di sinilah aturan diberlakukan. Setter memeriksa terlebih dahulu dan memanggil stop() sebelum apa pun diubah, sehingga object tetap valid:
make_account <- function(balance = 0) {
withdraw <- function(x) {
if (x <= 0) stop("amount must be positive", call. = FALSE)
if (x > balance) stop("insufficient funds", call. = FALSE)
balance <<- balance - x
}
list(withdraw = withdraw, balance = function() balance)
}
acc <- make_account(50)
msg <- tryCatch(acc$withdraw(80), error = function(e) conditionMessage(e))
cat(msg, "/", acc$balance())Output:
insufficient funds / 50lockBinding("rate", e) membuat satu variabel dalam sebuah environment hanya bisa dibaca. Jika kamu menetapkan nilai baru padanya setelah itu, akan terjadi error, sedangkan variabel lainnya tetap bisa ditulis:
loan <- new.env()
loan$rate <- 0.05
loan$owed <- 1000
lockBinding("rate", loan)
loan$owed <- 900
msg <- tryCatch({ loan$rate <- 0; "changed" }, error = function(e) conditionMessage(e))
cat(msg, "\n")
cat(loan$rate, loan$owed, "\n")Output:
cannot change value of locked binding for 'rate'
0.05 900 lockEnvironment(e) mencegah penambahan variabel baru. Dengan bindings = TRUE, fungsi ini juga mengunci semua variabel yang sudah ada, sehingga seluruh object menjadi hanya-baca:
cfg <- new.env()
cfg$theme <- "dark"
lockEnvironment(cfg, bindings = TRUE)
for (step in c("change", "add")) {
msg <- tryCatch({
if (step == "change") cfg$theme <- "light" else cfg$size <- 12
"done"
}, error = function(e) conditionMessage(e))
cat(step, ":", msg, "\n")
}Output:
change : cannot change value of locked binding for 'theme'
add : cannot add bindings to a locked environment local() menjalankan kode di environment baru dan mengembalikan nilai terakhirnya. Fungsi pembantu yang didefinisikan di dalamnya tetap tersembunyi. Dengan cara ini, sebuah file dapat menjaga fungsi tetap privat meskipun source() memasukkan semua hal lainnya ke environment global:
circle_area <- local({
square <- function(x) x * x
function(r) pi * square(r)
})
print(round(circle_area(2), 2))
print(exists("square"))Output:
[1] 12.57
[1] FALSETantangan
MudahLengkapi fungsi factory make_account(owner) di Account.R. Saldo dimulai dari 0 dan riwayat privat mencatat setiap perubahan sebagai +50 atau -20. List yang dikembalikan memiliki empat fungsi:
deposit(x)berhenti denganamount must be positivekecuali jikaxlebih besar dari 0;withdraw(x)berhenti denganamount must be positiveatauinsufficient funds;balance()mengembalikan saldo;history()mengembalikan riwayat sebagai vektor karakter.
Lakukan pemeriksaan sebelum mengubah apa pun dan gunakan call. = FALSE. Kode yang disediakan membaca pemilik, lalu baris dep 50 atau wd 20, mencetak ok atau error: beserta pesannya untuk setiap baris, mencoba mengubah salinan riwayat, lalu mencetak saldo dan riwayat.
Tulis kodemu di Account.R. main.R berisi kode input/output yang disediakan dan tidak boleh diedit.
Coba sendiri
source("Account.R")
# Kode input/output yang disediakan: biarkan apa adanya
input <- suppressWarnings(readLines(file("stdin")))
acc <- make_account(input[1])
for (line in input[-1]) {
p <- strsplit(line, " ")[[1]]
amount <- as.numeric(p[2])
msg <- tryCatch({
if (p[1] == "dep") acc$deposit(amount) else acc$withdraw(amount)
"ok"
}, error = function(e) paste("error:", conditionMessage(e)))
cat(line, ": ", msg, "\n", sep = "")
}
h <- acc$history()
h[1] <- "tampered"
cat("balance: ", acc$balance(), "\n", sep = "")
cat("history: ", paste(acc$history(), collapse = ", "), "\n", sep = "")
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Object
1Dasar S3
Bekerja dengan fileList dengan classFungsi KonstruktorMethod print dan formatValidator dan helperUlasan: Suhu4Enkapsulasi di R
Closure sebagai objectEnvironment sebagai objectFungsi accessorMelindungi stateRangkuman: Meter Parkir2S3 Generics dan Method
Generics dan UseMethodMethod DefaultMethod untuk Base GenericsDasar-Dasar NextMethodRekap: Luas Bangun5S4 class
Mendefinisikan class S4Slots dan AksesPemeriksaan ValiditasMethod showRingkasan: Katalog Produk8Kelas Referensi
Mendefinisikan Kelas ReferensiPembaruan method dan fieldSemantik PenyalinanPewarisan dan callSuperRangkuman: Antrean Tugas11Proyek: Manajemen Perpustakaan
Buku dan AnggotaMeminjam BukuLatihan sendiri: Compiler R online