قواعد النطاق المعجمي
افهم كيف يعثر R على المتغيرات بالبحث في البيئات الأصلية.
قواعد النطاق المعجمي درس مجاني في R Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في R Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة R Academy 4 دروس في المجموع.
ما هو النطاق المعجمي؟
يعني النطاق المعجمي أن الدالة تبحث عن المتغيرات في المكان الذي عُرّفت فيه، لا في المكان الذي استُدعيت منه. تستخدم R النطاق المعجمي. وهذا سلوك يمكن توقعه: فالبيئة التي تبحث فيها الدالة ثابتة وقت إنشائها، لا وقت استدعائها.
x <- 'global'
f <- function() {
cat('x =', x, '\n') # looks where f was defined (global)
}
local({
x <- 'local to local block'
f() # still prints global x, not the local one
})النطاق المعجمي مقابل النطاق الديناميكي
في النطاق الديناميكي (المستخدم في بعض اللغات الأخرى)، كانت الدالة ستعثر على المتغير في بيئة الاستدعاء. أما R فتستخدم النطاق المعجمي: إذ تكون البيئة المحيطة وقت التعريف هي المعتمدة دائمًا. يجعل ذلك سلوك الدوال متسقًا بغض النظر عن المكان الذي تُستدعى منه.
val <- 100
make_adder <- function(n) {
# n is captured from the definition environment
function(x) x + n
}
add10 <- make_adder(10)
add20 <- make_adder(20)
cat(add10(5), '\n') # 15 — n=10 from definition
cat(add20(5), '\n') # 25 — n=20 from definitionالمتغيرات الحرة والإغلاقات
المتغير الموجود داخل دالة، وليس معلمة ولا تعيينًا محليًا، يُسمى متغيرًا حرًا. تبحث R عنه في البيئة المحيطة. وتُسمى الدالة التي تلتقط المتغيرات الحرة إغلاقًا.
base_rate <- 0.05 # free variable captured by f
f <- function(principal, years) {
principal * (1 + base_rate) ^ years
}
cat('5 yr return:', f(1000, 5), '\n')
# Even if we change base_rate later:
base_rate <- 0.08
cat('New rate return:', f(1000, 5), '\n')الإغلاقات تلتقط البيئات
في كل مرة تُستدعى فيها دالة مُنشئة، تلتقط الدالة المُعادة (الإغلاق) نسخة من البيئة المحيطة. تنتج الاستدعاءات المختلفة إغلاقات ذات قيم ملتقطة مختلفة — وهذا هو أساس مُنشئات الدوال.
power_fn <- function(exp) {
function(x) x ^ exp
}
square <- power_fn(2)
cube <- power_fn(3)
cat('square(4) =', square(4), '\n')
cat('cube(3) =', cube(3), '\n')المعامل <<-
يبحث <<- (تعيين السهم المزدوج) صعودًا في سلسلة الأصول عن رابط موجود، ثم يعدّله في مكانه. وإذا لم يُعثر على أي رابط، ينشئ رابطًا في البيئة العامة. وهو الأداة المستخدمة لتعديل متغير في نطاق محيط من داخل دالة.
count <- 0
increment <- function() {
count <<- count + 1
}
increment()
increment()
increment()
cat('count:', count, '\n')استخدام <<- مع الإغلاقات
أكثر استخدامات <<- شيوعًا وملاءمةً هو داخل الإغلاقات التي تحتاج إلى تحديث الحالة في بيئتها المحيطة. وينشئ ذلك دوالًا ذات حالة — أي دوالًا تحتفظ بذاكرة مستمرة بين الاستدعاءات.
make_counter <- function() {
n <- 0
list(
increment = function() n <<- n + 1,
get = function() n,
reset = function() n <<- 0
)
}
ctr <- make_counter()
ctr$increment()
ctr$increment()
cat('Count:', ctr$get(), '\n')
ctr$reset()
cat('After reset:', ctr$get(), '\n')النطاق في الدوال المتداخلة
عند تداخل الدوال، تستطيع الدالة الداخلية رؤية المتغيرات المعرّفة في الدالة الخارجية. وتصبح بيئة الدالة الخارجية البيئة المحيطة بالدالة الداخلية، فتتكوّن سلسلة.
outer <- function() {
greeting <- 'Hello'
inner <- function(name) {
# greeting comes from outer's environment
paste(greeting, name)
}
inner('World')
}
cat(outer(), '\n')البحث في سلسلة النطاق
عندما تبحث R عن متغير، فإنها تبحث في البيئات بالترتيب التالي: بيئة الدالة نفسها ← البيئة المحيطة ← البيئة المحيطة بالبيئة المحيطة ← ... ← العامة ← مسار البحث ← الأساسية ← الفارغة. وتكون أول مطابقة هي المعتمدة.
x <- 'global'
f <- function() {
x <- 'local to f'
g <- function() {
# g has no x, so looks in f's env
cat('g sees x =', x, '\n')
}
g()
}
f()environment() لدالة
يمكنك فحص البيئة المحيطة بأي دالة باستخدام environment(f). ويمكنك حتى تعيينها باستخدام environment(f) <- e، ما يغيّر المكان الذي تبحث فيه الدالة عن المتغيرات الحرة — وهي تقنية قوية ومتقدمة.
x <- 'global_x'
f <- function() x
cat('f sees:', f(), '\n')
# Change f's enclosing environment
my_env <- new.env(parent = emptyenv())
my_env$x <- 'env_x'
environment(f) <- my_env
cat('f now sees:', f(), '\n')إغلاق عملي: التخزين المؤقت للنتائج
يتيح النطاق المعجمي مع <<- التخزين المؤقت للنتائج: إذ تُخزَّن نتائج الدوال المكلفة في بيئة الإغلاق. وتكون الذاكرة المؤقتة خاصة بالإغلاق وتستمر بين الاستدعاءات.
make_memoized_fib <- function() {
cache <- c()
function(n) {
if (!is.null(cache[n])) return(cache[n])
if (n <= 1) { cache[n] <<- n; return(n) }
result <- Recall(n-1) + Recall(n-2)
cache[n] <<- result
result
}
}
fib <- make_memoized_fib()
cat(sapply(0:8, fib), '\n')مأزق النطاق المعجمي: متغيرات الحلقات
من المآزق الشائعة إنشاء إغلاقات داخل حلقة. إذ تلتقط جميع الإغلاقات البيئة نفسها، لا نسخة من القيمة. وعند استدعائها، يكون متغير الحلقة قد احتفظ بقيمته النهائية.
fns <- vector('list', 3)
for (i in 1:3) {
local({
captured_i <- i
fns[[captured_i]] <<- function() captured_i
})
}
cat(fns[[1]](), fns[[2]](), fns[[3]](), '\n')تحقق سريع
في النطاق المعجمي لدى R، أين تبحث الدالة عن متغير حر (أي متغير غير معرّف داخل الدالة نفسها)؟
النطاق المعجمي: أهم النقاط
أهم النقاط المتعلقة بالنطاق المعجمي:
- تستخدم R النطاق المعجمي — وتبحث الدوال عن المتغيرات حيث عُرّفت
- تلتقط الدالة بيئتها المحيطة بوصفها إغلاقًا
- تُحدَّد المتغيرات الحرة وقت التعريف، لا وقت الاستدعاء
- يعدّل
<<-رابطًا في سلسلة الأصول (أو في البيئة العامة إذا لم يُعثر عليه) - الإغلاقات +
<<-= دوال ذات حالة وبيانات خاصة مستمرة - مأزق إغلاقات الحلقات: استخدم
local()لفرض إنشاء بيئة جديدة في كل تكرار
make_multiplier <- function(factor) {
function(x) x * factor
}
double <- make_multiplier(2)
triple <- make_multiplier(3)
cat('double(7):', double(7), '\n')
cat('triple(7):', triple(7), '\n')
cat('double env factor:', get('factor', envir = environment(double)), '\n')الأسئلة الشائعة
هل درس «قواعد النطاق المعجمي» مجاني؟
نعم — نص درس «قواعد النطاق المعجمي» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة R Academy، انتقل إلى CoddyKit PRO. تتضمن دورة R Academy 4 دروس في المجموع.
ماذا ستتعلم في «قواعد النطاق المعجمي»؟
افهم كيف يعثر R على المتغيرات بالبحث في البيئات الأصلية. تتمرن على R Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ R Academy؟
لا تُشترط خبرة سابقة. R Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «قواعد النطاق المعجمي»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس R Academy هذا؟
نعم. كل درس في R Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- ما البيئة في R؟
- قواعد النطاق المعجمي
- النطاق العام مقابل المحلي
- إنشاء البيئات وفحصها