روبي على القضبان:تهيئة متغيرات المثيل مع عرض المساعدين

StackOverflow https://stackoverflow.com/questions/2128406

سؤال

أواجه نوعًا ما من مشكلة النطاق التي تمنع تهيئة متغيرات المثيل بشكل صحيح بواسطة المساعدين الذين يتم استدعاؤهم من العرض.

#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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top