Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

التحقق باستخدام 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"
challenge icon

التحدي

سهل

يحتوي فهرس على كتب وكتب إلكترونية وأقراص 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))
  }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم R عبر الإنترنت