Menu
CoddyTech

Environment sebagai object

Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan R di Coddy. Pelajaran 18 dari 57.

Sebuah environment adalah kumpulan nilai bernama, seperti list, yang dibuat dengan new.env(). Bedanya, sebuah environment tidak pernah disalin: setiap variabel yang merujuk kepadanya melihat object yang sama, sehingga perubahan melalui satu nama terlihat melalui semuanya:

e <- new.env()
e$count <- 1
alias <- e
alias$count <- 99
print(e$count)
l <- list(count = 1)
copy <- l
copy$count <- 99
print(l$count)

Output:

[1] 99
[1] 1

Fungsi yang menerima sebuah environment mengubah object milik pemanggil. Fungsi ini tidak harus mengembalikan apa pun, dan pemanggil tidak menetapkan hasilnya ke variabel:

deposit <- function(acc, x) acc$balance <- acc$balance + x
acc <- new.env()
acc$balance <- 10
deposit(acc, 5)
deposit(acc, 5)
print(acc$balance)

Output:

[1] 20

assign(), get(), dan exists() bekerja dengan nama yang disimpan dalam variabel, dan ls() mencantumkan nama-nama dalam environment menurut urutan abjad:

e <- new.env()
for (fruit in c("pear", "apple")) assign(fruit, nchar(fruit), envir = e)
print(ls(e))
print(get("pear", envir = e))
print(exists("kiwi", envir = e))

Output:

[1] "apple" "pear" 
[1] 4
[1] FALSE

Sebuah environment dengan atribut class adalah object S3 dengan semantik referensi: method-nya bekerja seperti biasa, dan fungsi yang mengubahnya melakukannya langsung pada object tersebut:

new_wallet <- function(coins = 0) {
  w <- new.env()
  w$coins <- coins
  class(w) <- "wallet"
  w
}
print.wallet <- function(x, ...) {
  cat("wallet with", x$coins, "coins\n")
  invisible(x)
}
spend <- function(w, n) w$coins <- w$coins - n
w <- new_wallet(10)
spend(w, 3)
w

Output:

wallet with 7 coins
challenge icon

Tantangan

Mudah

Inventaris adalah environment dengan class inventory dan satu variabel, items, yaitu vektor numerik bernama yang berisi stok. Lengkapi Inventory.R:

  • new_inventory() membuat environment dengan items kosong (c() sudah cukup) dan class.
  • add_stock(inv, item, n) menambahkan n ke stok item, dimulai dari 0 untuk item baru.
  • take_stock(inv, item, n) mengurangi n dan mengembalikan TRUE jika stok mencukupi, jika tidak, tidak mengubah apa pun dan mengembalikan FALSE.
  • stock_of(inv, item) mengembalikan stok, yaitu 0 untuk item yang tidak dikenal.

Fungsi-fungsi tersebut mengubah inventaris secara langsung dan tidak mengembalikannya. Kode yang disediakan membaca perintah add apple 5 dan take apple 2, mencetak hasil setiap take, lalu mencetak setiap item dalam urutan alfabetis.

Tulis kodemu di Inventory.R. main.R berisi kode input/output yang disediakan dan tidak boleh diedit.

Coba sendiri

source("Inventory.R")

# Kode input/output yang disediakan: biarkan apa adanya
input <- suppressWarnings(readLines(file("stdin")))
inv <- new_inventory()
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  n <- as.numeric(p[3])
  if (p[1] == "add") add_stock(inv, p[2], n)
  if (p[1] == "take") cat("take ", p[2], ": ", if (take_stock(inv, p[2], n)) "ok" else "not enough", "\n", sep = "")
}
for (item in sort(names(inv$items))) cat(item, ": ", stock_of(inv, item), "\n", sep = "")
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Object

Latihan sendiri: Compiler R online