أدوات التحقق والمساعدة
جزء من قسم البرمجة كائنية التوجه في رحلة R على Coddy. الدرس 5 من 57.
يتحقق المُنشئ من الأنواع؛ بينما يتحقق المُدقِّق من القيم. وفقًا للعرف، تأخذ validate_money() كائنًا، وتستدعي stop() برسالة واضحة لكل قاعدة يخالفها، وتُعيد الكائن عندما يكون كل شيء على ما يرام. تحافظ call. = FALSE على استبعاد استدعاء الدالة من الرسالة:
new_money <- function(amount = double(), currency = character()) {
stopifnot(is.double(amount), is.character(currency))
structure(list(amount = amount, currency = currency), class = "money")
}
validate_money <- function(x) {
if (x$amount < 0) stop("amount must not be negative", call. = FALSE)
if (nchar(x$currency) != 3) stop("currency must have 3 letters", call. = FALSE)
x
}
m <- validate_money(new_money(-5, "EUR"))الناتج:
Error: amount must not be negative
Execution haltedإن المساعد هو الدالة التي تستدعيها تعليمات برمجية أخرى. وتُسمّى باسم الفئة، وتحول مدخلاتها إلى الأنواع الصحيحة، وتملأ القيم الافتراضية، وتمرر النتيجة عبر المُنشئ ومدقّق الصحة:
new_money <- function(amount = double(), currency = character()) {
stopifnot(is.double(amount), is.character(currency))
structure(list(amount = amount, currency = currency), class = "money")
}
validate_money <- function(x) {
if (x$amount < 0) stop("amount must not be negative", call. = FALSE)
x
}
money <- function(amount, currency = "EUR") {
validate_money(new_money(as.double(amount), toupper(currency)))
}
m <- money("12", "usd")
cat(m$amount, m$currency)الناتج:
12 USDيلتقط الكود الذي يقرأ إدخال المستخدم أخطاء أداة التحقق باستخدام tryCatch() ويعرض conditionMessage(e)، وهو النص المُمرَّر إلى stop():
validate_age <- function(x) {
if (x$years < 0) stop("age must not be negative", call. = FALSE)
if (x$years > 150) stop("age is too large", call. = FALSE)
x
}
age <- function(years) validate_age(structure(list(years = as.double(years)), class = "age"))
for (input in c("30", "-2", "200")) {
result <- tryCatch(paste("ok", age(input)$years), error = function(e) conditionMessage(e))
cat(result, "\n")
}الناتج:
ok 30
age must not be negative
age is too large لكل واحدة من الدوال الثلاث مهمة واحدة. new_money() صارمة وسريعة، ومخصّصة للتعليمات البرمجية التي تحتوي بالفعل على الأنواع الصحيحة. validate_money() تتولى القواعد المتعلقة بالقيم، والتي قد تكون بطيئة أو كثيرة. money() ودودة، وهي ما يستخدمه باقي البرنامج:
new_money() # أنواع فقط؛ يبني الكائن باستخدام structure()
validate_money() # قواعد القيمة؛ stop() مع رسالة، وإلا أرجع x
money() # يحول المدخل، ثم validate_money(new_money(...))التحدي
سهلتُنشئ new_score(points, max) في Score.R كائن score. أكمل الدوال الأخرى في الملف نفسه:
- تتوقف
validate_score(x)معpoints must not be negativeأوmax must be positiveأوpoints must not exceed max، مع التحقق منها بهذا الترتيب، وإلا تُرجعx. - تحوّل
score(points, max = 100)الوسيطتين باستخدامas.double()وتُرجعvalidate_score(new_score(...)). - تُرجع
format.score(x, ...)القيمة45/50 (90%)، مع تقريب النسبة المئوية إلى عدد صحيح.
استخدم call. = FALSE في كل استدعاء لـ stop(). يقرأ الكود المُزوَّد الأسطر 45 50، ويطبع النتيجة المنسَّقة، أو error: والرسالة.
ضع الكود في Score.R. يحتوي main.R على كود الإدخال/الإخراج المُزوَّد، ولا يمكن تعديله.
جرّب بنفسك
source("Score.R")
# كود الإدخال/الإخراج المُزوَّد: أبقه كما هو
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, " ")[[1]]
s <- tryCatch(score(p[1], p[2]), error = function(e) conditionMessage(e))
if (is.character(s)) cat("error: ", s, "\n", sep = "") else cat(format(s), "\n", sep = "")
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1أساسيات S3
التعامل مع الملفاتالقوائم باستخدام فئةدوال المُنشئأساليب الطباعة والتنسيقأدوات التحقق والمساعدةمراجعة - درجات الحرارة2S3 الدوال العامة والطرق
الدوال العامة وUseMethodالطرق الافتراضيةطرق الدوال العامة الأساسيةأساسيات NextMethodمراجعة - مساحات الأشكالتدرّب بنفسك: مترجم R عبر الإنترنت