التابع ?Proc.lambda في روبي

من موسوعة حسوب
< Ruby‏ | Proc
مراجعة 07:54، 26 نوفمبر 2018 بواسطة محمد-خطيب (نقاش | مساهمات)
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)

يتحقَّق التابع ?lambda إذا كانت معالجة الوسائط صارمةً في الكائن Proc (أي يجب تمرير نفس العدد تمامًا من الوسائط المعرَّفة عند إنشاء الكائن). تُنشأ هذه الكائنات عادةً بوساطة lambda.

كائنات الصنف Proc المُنشأة بوساطة proc ليست صارمةً وتمتلك الميزات التالية:

  • تتجاهل الوسائط الإضافيَّة:
proc {|a,b| [a,b] }.call(1,2,3)    #=> [1,2]
  • تُعيِّن القيمة nil للوسائط الناقصة:
proc {|a,b| [a,b] }.call(1)        #=> [1,nil]
  • توسِّع وسيط مصفوفة مفردة:
proc {|a,b| [a,b] }.call([1,2])    #=> [1,2]

كائن الصنف Proc المُنشأ بواسطة lambda لا يمتلك هذه الميِّزات.

lambda {|a,b| [a,b] }.call(1,2,3)  #=> ArgumentError
lambda {|a,b| [a,b] }.call(1)      #=> ArgumentError
lambda {|a,b| [a,b] }.call([1,2])  #=> ArgumentError

التابع ?lambda هو تابعٌ خَبَريٌ (predicate) لهذه الميِّزات. يُعيد القيمة true إذا لم تُطبَّق أي ميِّزة.

lambda {}.lambda?            #=> true
proc {}.lambda?              #=> false

يؤدي التابع new نفس عمل proc.

Proc.new {}.lambda?          #=> false

تحافظ lambda و proc و new على ميزات كائن الصنف Proc المعطيَّة بالوسيط &.

lambda(&lambda {}).lambda?   #=> true
proc(&lambda {}).lambda?     #=> true
Proc.new(&lambda {}).lambda? #=> true

lambda(&proc {}).lambda?     #=> false
proc(&proc {}).lambda?       #=> false
Proc.new(&proc {}).lambda?   #=> false

يمتلك كائن الصنف Proc المُنشَأ عبر الوسيط & تلك الميزات.

def n(&b) b.lambda? end
n {}                         #=> false

يحتفظ الوسيط & بهذه الميِّزات إذا أُعطي كائن الصنف Proc عبر الوسيط &.

n(&lambda {})                #=> true
n(&proc {})                  #=> false
n(&Proc.new {})              #=> false

لا يمتلك كائن Proc المُحوَّل من تابع أي ميِّزات.

def m() end
method(:m).to_proc.lambda?   #=> true

n(&method(:m))               #=> true
n(&method(:m).to_proc)       #=> true

يُعامَل define_method كما يُعامل تعريف التابع. لا يمتلك التابع المُعرَّف أية ميِّزات.

class C
  define_method(:d) {}
end
C.new.d(1,2)       #=> ArgumentError
C.new.method(:d).to_proc.lambda?   #=> true

يُعرِّف define_method تابعًا من دون ميِّزات دومًا حتى إذا أُعطي كائنٌ من النوع Proc لم يُنشأ باستعمال lambda. هذا الاستثناء الوحيد الذي لا تُحفظ فيه الميِّزات.

class C
  define_method(:e, &proc {})
end
C.new.e(1,2)       #=> ArgumentError
C.new.method(:e).to_proc.lambda?   #=> true

يَضمن هذا الاستثناء أنَّ التوابع لا تمتلك ميِّزاتٍ ويجعل من السَّهل على المُغلِّفات (wrappers) تعريف التوابع التي تسلك سلوكًا طبيعيًّا.

class C
  def self.def2(name, &body)
    define_method(name, &body)
  end

  def2(:f) {}
end
C.new.f(1,2)       #=> ArgumentError

يُعرَّف المُغلِّف def2 تابعًا لا يمتلك ميِّزات.

البنية العامة

lambda?  true or false

القيم المعادة

تُعاد القيمة true إذا كانت معالجة الوسائط صارمةً، أو تعاد القيمة false خلاف ذلك.

انظر أيضًا

  • التابع hash: يحسب قيمة التجزئة الموافقة لجسم الكتلة proc التي استدعيت معه ثمَّ يعيدها.
  • التابع to_proc: يُعدُّ جزءًا من البروتوكول المستخدم في تحويل الكائنات إلى كائناتٍ من الصنف Proc.
  • المعامل ===: يستدعي الكتلة بتمرير الكائن الواقع على يمينه كمعاملٍ للنسخة proc.
  • التابع call: يستدعي الكتلة المرتبطة بالمتغير الذي استعمل معه مُعيِّنًا معاملات الكتلة إلى القيم المعطاة ضمنه ويُعيد المعامل قيمة آخر تعبيرٍ قُيِّم في الكتلة.

مصادر