روبي على القضبان:تهيئة متغيرات المثيل مع عرض المساعدين
-
22-09-2019 - |
سؤال
أواجه نوعًا ما من مشكلة النطاق التي تمنع تهيئة متغيرات المثيل بشكل صحيح بواسطة المساعدين الذين يتم استدعاؤهم من العرض.
#sample_controller.rb
class SampleController < ApplicationController
def test
end
end
#application_controller.rb
helper_method :display
def display
if not defined? @display
return @display = "a"
else
return @display += "a"
end
end
#test.html.erb
<%= display %>
<%= display %>
<%= @display %>
<%= @display.reverse %>
عندما يتم عرض العينة/الاختبار، فإنها تنتهي مع ظهور خطأ "أثناء تقييم nil.reverse".وهذا أمر مثير للدهشة لأن أول مكالمتين للعرض كان يجب أن تتم تهيئة @display كما كنت أعتقد.إذا تمت إزالة <%= @display.reverse %> فإن الإخراج هو "aa"، مما يشير إلى أنه يتم تعيين متغير مثيل @display بواسطة الأسلوب المساعد، ولكن لا يمكن الوصول إليه في العرض.
إذا تم تعديل وحدة التحكم لتصبح (برمز العرض الأصلي):
class SampleController < ApplicationController
def test
display
end
end
يصبح الإخراج "aa aaa a a".إذا قمت بإجراء مكالمتين للعرض في وحدة التحكم، أحصل على "aaa aaaa aa".لذلك يبدو أن الاستدعاءات التي يتم إجراؤها في وحدة التحكم فقط هي التي ستعدل متغير مثيل SampleController، بينما ستعدل الاستدعاءات في العرض متغير مثيل لـ ApplicationController الذي لا يمكن للعرض الوصول إليه.
هل هذا خطأ في Rails أم أنني أسيء فهم هذه الوظيفة المقصودة لسبب ما؟
السياق الذي واجهت فيه هذا الخطأ هو محاولة إنشاء ملف logged_in؟أسلوب ApplicationController الذي يقوم بإعداد متغير @user في المرة الأولى التي يتم استدعاؤه فيه، ويعيد صواب أو خطأ إذا قام المستخدم بتسجيل الدخول.لن ينجح هذا إلا إذا قمت بإضافة مكالمة غير ضرورية في وحدة التحكم قبل محاولة استخدامها في العرض.
المحلول
يوجد نوعان من @display ivars في وقت العرض، أحدهما في وحدة التحكم والآخر في العرض.لا يمكن للعرض الوصول إلى العرض الموجود في وحدة التحكم والعكس صحيح.في بداية عملية التصيير، يقوم ريلز بنسخ كافة متغيرات وحدة التحكم في العرض.ولكن في ذلك الوقت @display غير موجود ولم يتم نسخه.في أي برنامج روبي، فإن الاتصال بـ @my_undef_ivar سيعيد صفرًا - وهذا بالضبط ما يحدث لك.
يمكن أن يكون مربكا، وهنا يقال بطريقة أخرى.ينسخ ريلز ivars من وحدة التحكم إلى العرض في بداية التصيير.لذا، فإن التغييرات في ivar الخاص بالعرض لا تنعكس في ivar الخاص بوحدة التحكم، والعكس صحيح.يتيح المساعد الذي حددته للعرض استدعاء طريقة على وحدة التحكم بحيث يمكن إرجاع ivar الخاص بوحدة التحكم إلى العرض كقيمة إرجاع ولكن التغيير الذي تم إجراؤه على ivar لوحدة التحكم نفسها لا ينعكس في ivar الآخر، طريقة العرض.
ما عليك سوى استخدام الطريقة المساعدة في هذه الحالة ونسيان @display في العرض.
نصائح أخرى
أعتقد أن هذا قد يكون الثاني الكلمات المحجوزة قضية رأيتها هذا الأسبوع ...
نصيحة: لا تحتاج أبدًا إلى استخدام return
الكلمة الرئيسية في روبي. أيضا ، استخدامك ل defined?
هل يخيفني ... قد يستحق تجربة هذا:
if @display.nil?
@display = "a"
else
@display += "a"
end