בדיקה באמצעות inherits()
חלק מהיחידה תכנות מונחה עצמים במסלול ה-R של Coddy. שיעור 15 מתוך 57.
inherits(x, "employee") בודקת אם employee מופיע איפשהו בווקטור המחלקות של x, ולכן היא מחזירה TRUE גם עבור מנהלים. השוואה עם class(x) == "employee" בודקת כל מיקום בנפרד ומחזירה וקטור, דבר שגורם לכשל בתוך if:
m <- structure(list(), class = c("manager", "employee"))
print(inherits(m, "employee"))
print(inherits(m, "intern"))
print(class(m) == "employee")פלט:
[1] TRUE
[1] FALSE
[1] FALSE TRUEבהינתן כמה שמות, inherits() מחזירה TRUE כאשר האובייקט שייך לאחד מהם. עם which = TRUE היא מחזירה, עבור כל שם, את מיקומו בווקטור המחלקות, או 0 אם הוא חסר:
p <- structure(list(), class = c("fragile", "express", "parcel"))
print(inherits(p, c("letter", "parcel")))
print(inherits(p, c("express", "letter", "parcel"), which = TRUE))פלט:
[1] TRUE
[1] 2 0 3פונקציה שמתאימה רק למשפחה אחת של מחלקות בודקת את הארגומנט שלה באמצעות inherits() ועוצרת עם הודעה ברורה אחרת:
raise <- function(x, pct) {
if (!inherits(x, "employee")) stop("raise() needs an employee", call. = FALSE)
x$salary <- x$salary * (1 + pct / 100)
x
}
m <- structure(list(salary = 50000), class = c("manager", "employee"))
print(raise(m, 10)$salary)
print(tryCatch(raise(list(salary = 1), 10), error = function(e) conditionMessage(e)))פלט:
[1] 55000
[1] "raise() needs an employee"Filter() יחד עם inherits() בוחרת את האיברים השייכים למשפחה אחת מתוך רשימה מעורבת, כולל כל תת־המחלקות:
staff <- list(
structure(list(name = "Ada"), class = c("manager", "employee")),
structure(list(name = "Bo"), class = "employee"),
structure(list(name = "Cy"), class = c("intern", "employee")),
structure(list(name = "Dee"), class = c("director", "manager", "employee"))
)
managers <- Filter(function(x) inherits(x, "manager"), staff)
print(vapply(managers, function(x) x$name, character(1)))פלט:
[1] "Ada" "Dee"אתגר
קלקטלוג מכיל ספרים, ספרים אלקטרוניים ותקליטורי DVD. הבנאים מוגדרים בקבצים Item.R, Book.R, Ebook.R ו־Dvd.R; לספר אלקטרוני יש את המחלקה c("ebook", "book", "item"). בקובץ Catalogue.R השלימו שתי פונקציות באמצעות inherits():
count_of(items, kind)מחזירה כמה פריטים כוללים אתkindבמקום כלשהו בווקטור המחלקות שלהם.titles_of(items, kind)מחזירה את הכותרות של הפריטים האלה, לפי הסדר שלהם.
הקוד שסופק קורא את השורות book Dune, ebook Emma, dvd Alien ומבצע את השאילתה ? book, ומדפיס book: 2 (Dune, Emma), או רק dvd: 0 כשאין התאמות.
הקוד שלך צריך להיות בקבצים Item.R, Book.R, Ebook.R, Dvd.R ו־Catalogue.R. הקובץ main.R מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.
נסו בעצמכם
source("Item.R")
source("Book.R")
source("Ebook.R")
source("Dvd.R")
source("Catalogue.R")
# קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
input <- suppressWarnings(readLines(file("stdin")))
items <- list()
for (line in input) {
p <- strsplit(line, " ")[[1]]
rest <- paste(p[-1], collapse = " ")
if (p[1] == "?") {
titles <- titles_of(items, p[2])
shown <- if (length(titles) > 0) paste0(" (", paste(titles, collapse = ", "), ")") else ""
cat(p[2], ": ", count_of(items, p[2]), shown, "\n", sep = "")
} else {
items[[length(items) + 1]] <- switch(p[1], book = new_book(rest), ebook = new_ebook(rest), dvd = new_dvd(rest))
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות S3
עבודה עם קבציםרשימות עם מחלקהפונקציות בנאימתודות print ו-formatמאמתים ופונקציות עזרחזרה – טמפרטורות3ירושה ב-S3
וקטורי מחלקהסדר חיפוש המתודותהרחבה באמצעות NextMethodבדיקה באמצעות inherits()סיכום – שכר העובדיםתרגלו בעצמכם: קומפיילר R אונליין