סמנטיקת העתקה
חלק מהיחידה תכנות מונחה עצמים במסלול ה-R של Coddy. שיעור 39 מתוך 57.
אובייקטים מסוג S3 ו-S4 הם ערכים: פונקציה שמשנה אחד מהם משנה את העותק שלה. אובייקטים מסוג RC הם הפניות: האובייקט של הקורא משתנה. אותה פונקציה מתנהגת אחרת עבור שני הסוגים:
setClass("S4Box", slots = c(n = "numeric"))
RCBox <- setRefClass("RCBox", fields = list(n = "numeric"))
bump_s4 <- function(b) { b@n <- b@n + 1; invisible(b) }
bump_rc <- function(b) b$n <- b$n + 1
v <- new("S4Box", n = 1)
r <- RCBox$new(n = 1)
bump_s4(v)
bump_rc(r)
cat(v@n, r$n)פלט:
1 2$copy() יוצרת אובייקט חדש ועצמאי עם אותם ערכי שדות. שינוי העותק לא משנה את המקור:
Account <- setRefClass("Account", fields = list(balance = "numeric"))
a <- Account$new(balance = 100)
alias <- a
backup <- a$copy()
alias$balance <- 0
cat(a$balance, backup$balance)פלט:
0 100רשימה יכולה להכיל את אותו אובייקט RC כמה פעמים. שינוי של איבר אחד משנה את כולם. צרו אובייקט חדש לכל איבר כאשר הם צריכים להיות בלתי תלויים:
Counter <- setRefClass("Counter", fields = list(n = "numeric"))
one <- Counter$new(n = 0)
same <- list(one, one, one)
same[[1]]$n <- 5
fresh <- lapply(1:3, function(i) Counter$new(n = 0))
fresh[[1]]$n <- 5
cat(same[[3]]$n, fresh[[3]]$n)פלט:
5 0identical(a, b) מחזיר TRUE עבור שני שמות של אותו אובייקט RC, ו-FALSE עבור עותק, גם כאשר השדות עדיין שווים:
Account <- setRefClass("Account", fields = list(balance = "numeric"))
a <- Account$new(balance = 100)
b <- a
c2 <- a$copy()
cat(identical(a, b), identical(a, c2), c2$balance == a$balance)פלט:
TRUE FALSE TRUEאתגר
קלעורך טקסט שומר נקודות שמירה. הכריזו על מחלקת הייחוס Document בתוך Document.R עם השדה text (character) ועם המתודה type(s), שמוסיפה את s לטקסט. לאחר מכן כתבו את checkpoint(doc), שמחזירה עותק עצמאי של המסמך.
ההגדרה עם המתודות עטופה ב־suppressMessages(). הקוד שסופק מתחיל בנקודת שמירה, ואז קורא פקודות: save שומרת את checkpoint(doc), הפקודה undo חוזרת לעותק של נקודת השמירה האחרונה, וכל שורה אחרת מוקלדת. אחרי כל פקודה הקוד מדפיס את הטקסט ואת הטקסט שנשמר, לכן נקודת שמירה לעולם לא צריכה להשתנות בזמן שממשיכים להקליד.
הקוד שלך צריך להופיע ב־Document.R. הקובץ main.R מכיל את קוד הקלט/פלט שסופק, ואי אפשר לערוך אותו.
נסו בעצמכם
source("Document.R")
# קוד הקלט/פלט שסופק: השאירו אותו כפי שהוא
input <- suppressWarnings(readLines(file("stdin")))
doc <- Document$new(text = "")
saved <- checkpoint(doc)
for (cmd in input) {
if (cmd == "save") {
saved <- checkpoint(doc)
} else if (cmd == "undo") {
doc <- checkpoint(saved)
} else {
doc$type(cmd)
}
cat(cmd, " -> [", doc$text, "] saved [", saved$text, "]\n", sep = "")
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות S3
עבודה עם קבציםרשימות עם מחלקהפונקציות בנאימתודות print ו-formatמאמתים ופונקציות עזרחזרה – טמפרטורותתרגלו בעצמכם: קומפיילר R אונליין