روبي: استخدام الكلمة الرئيسية ما لم يكن مع بيان الإرجاع

أنا أعمل حاليًا في مشروع يوجد به رمز يبدو كالتالي:

  # the first return is the one causing problems
  def collect
    return Hash["IdentANode", Array[@id, ",", @ident_a_node.collect]] unless @ident_a_node.nil? and @id.nil?
    return Hash["IdentANode", @id] unless @id.nil?
  end

حيث يمكنني استخدام عامل التشغيل ما لم يتم تنفيذ بيان الإرجاع بشكل مشروط. لسبب ما ، يتم تنفيذ هذه الشفرة الثابتة حتى إذا كانت ident_a_node هي لا . عند التنفيذ ، أحصل على هذه الرسالة:

IDANode.rb: 14: في collect ': unefined method collect' for   nil: NilClass (NoMethodError)

وهو ما يربكني لأنني كنت أعتقد أن الكلمة الرئيسية قد تمنع حدوث ذلك. عندما أقوم بتغيير العبارة إلى هذا النموذج:

if not @ident_a_node.nil? and not @id.nil?
  return Hash["IdentANode", Array[@id, ",", @ident_a_node.collect]]
end  

أو هذا الشكل:

return Hash["IdentANode", Array[@id, ",", @ident_a_node.collect]] if not @ident_a_node.nil? and not @id.nil?

بيان الإرجاع لا أعدم ، ما الذي يعطي؟ لماذا يوجد فرق بين هذين البيانين؟ هل يؤدي وجود شروط متعددة مع الكلمة ما لم إلى حدوث مشكلات؟

سيكون موضع تقدير أي أفكار

0

2 إجابة

لديك فشل منطقي هناك. أنت تختبر كلاهما nil لتجنب تشغيله عندما يجب عليك اختباره إذا إما لا >. ربما حصلت على نفسك في هذا الموقف من خلال وجود طبقات كثيرة من النفي. أي شيء أكثر من واحد غير مقبول.

بعبارة أخرى ، يمكنك الابتعاد "إذا لم تمطر" ولكن لا يجب استخدام أشياء مثل "ما لم يتم تعيين العلامة is_not_raining على عكس false".

رأيي الشخصي هو أنه لا ينبغي استخدام الشروط الخلفية إلا إذا كان من الواضح أنها موجودة. كما ترى في المثال الخاص بك ، يجب عليك التمرير أفقيًا للعثور على الشرط ، لإخفاء معلومات مهمة من المطور.

كمسألة نمط ، لا تستخدم لا عندما ! ستقوم بنفس المهمة. ثانيًا ، أنت تختبر تحديدًا ضد nil عندما تريد على الأرجح قيمة محددة من نوع ما.

تتضمن المشكلات الأخرى استخدام Hash [] و Array [] وهي بالتأكيد عناصر من استخدام لغة تتطلبها. روبي ، مثل جافا سكريبت ، يسمح بالتعريف الضمني عن ذلك باستخدام {} و [] على التوالي.

إصدار صحيح من نمط روبي الخاص بك هو:

if (@ident_a_node and @id)
  return { "IdentANode" => [ @id, ",", @ident_a_node.collect ] }
end  
0
وأضاف
NiklasB. أوافق على أن إجبار اللغات مثل جافا يعد سلبيًا كبيرًا ، ولكنه انتقال صعب بالنسبة لي ، كل ما أعرفه عن البرمجة يأتي من هذا النموذج من الإسهاب
وأضاف المؤلف Hunter McMillen, مصدر
شكرا لك، كان ذلك مفيدا جدا.
وأضاف المؤلف Hunter McMillen, مصدر
ما أعمله في طريقة التجميع هو إرجاع "التجزئة" ، لذا إذا كانت القيمة صفرًا ، فيجب أن تُرجع "التجزئة" بقيمة لا شيء. {"IdentANode" => nil}
وأضاف المؤلف Hunter McMillen, مصدر
السبب الرئيسي في اختيار استخدام ما لم يكن ذلك لأن لدي الكثير من هذه الشروط الشرطية ووجود بيان if لكل من شأنه أن يجعل رمز messier في رأيي.
وأضاف المؤلف Hunter McMillen, مصدر
أيضا ، هل هناك دليل جيد للأسلوب للإشارة إلى أشياء مثل Hash [] و Array [] مقابل {key => value} و [] ؟؟
وأضاف المؤلف Hunter McMillen, مصدر
NiklasB. تأتي غالبية تجربتي في البرمجة من Java و C ، ولا توجد حرفية لهذه الأشياء في Java و C
وأضاف المؤلف Hunter McMillen, مصدر
@ هونتر: أعتقد أن هذا ليس مشكلة كبيرة. تعتمد معظم هذه اللغات على واحد إلى ثلاثة من بنى البيانات الأساسية التي يتم استخدامها على نطاق واسع جدًا في كل تطبيق. بالنسبة إلى روبي ، هذه صفائف ، ورموز ، ورموز ربما (لم أقم بتضمين سلاسل هنا لأنك يجب أن تستخدم في تركيبتها من جافا). إذا كنت تعرف كيف ومتى تستخدمها ، فسيكون ذلك انتقالًا سهلاً :)
وأضاف المؤلف Niklas B., مصدر
@ هونتر: حسنا ، يفعلون في معظم اللغات الحديثة ، مثل JavaScript ، Python ، LISP (Clojure ، Scheme ، CL ، ...) ، Scala ، Haskell ، ... Actually C منخفض جدًا ، ولا يحتوي على في بنية البيانات باستثناء المصفوفات (التي توجد بها بنية التهيئة). حقيقة أن جافا ليس لديها شيء من هذا القبيل هو bummer ضخمة ، IMHO (ولكن لديها أيضا الجديد int [] {1 ، 2 ، 3} شيء).
وأضاف المؤلف Niklas B., مصدر
Hunter: أليس من الواضح أن الحرفيين أنظف من الصانعين واضحة عندما تكون متاحة؟ أما بالنسبة لأسلوب ruby العام ، فأنا أحب إرشادات Github ruby
وأضاف المؤلف Niklas B., مصدر
لماذا الرجوع ؟ سأفعل فقط إذا ...؛ [EXPR]. آخر؛ لا شيء. نهاية (لتوضيح أن nil يتم إرجاعها في حالة الفشل)
وأضاف المؤلف Niklas B., مصدر

لا تستخدم إلا مع و/أو ، إنها مجرد مربكة. ما لم يكن @ ident_a_node.nil؟ و @ id.nil؟ تعني if! (@ ident_a_node.nil؟ و @ id.nil؟) ، مما يعني أنه سيعود عندما لا يكون أحد متغيري الحالة السابقين لا شيء.

if !(@ident_a_node.nil? and @id.nil?)

بالضبط مثل

if [email protected]_a_node.nil? or [email protected]?

مما يجعلها أكثر وضوحًا ، ولماذا لا تكون هي نفسها

if not @ident_a_node.nil? and not @id.nil?
0
وأضاف
لسبب ما كنت أتوقع ترجمة مثل هذا: if! first_condition و! second_condition شكرا جزيلا لك
وأضاف المؤلف Hunter McMillen, مصدر
حاولت استخدام ما لم الطريقNiklasB. النصائح ، لا تزال القضية نفسها. ما لم يكن أمرًا صعبًا.
وأضاف المؤلف iGbanam, مصدر
في الواقع ، أعتقد أنه يعجبني أكثر لأنه يحتوي على نفس الدلالات مثل تأكيد . في الأساس يمكننا تبديل العودة إلا إذا كانت مع تؤكد أو رفع ArgumentError ، "..." ما لم في أي وقت.
وأضاف المؤلف Niklas B., مصدر
Yasky: أرى ما تقصد. OP على الأرجح تعني return ifident_a_node andid . لا حاجة لاستخدام لا شيء؟ (يجب أن أكون فوق ذلك). أعتبر هذا المنظف من المكافئ بالعودة إذا @ ident_a_node.nil؟ أو @ id.nil؟
وأضاف المؤلف Niklas B., مصدر
dominik: ما لم يسمح لك بالتعبير عن ظروفك بلغة إنجليزية بسيطة. وعلاوة على ذلك ، فإن تعود ما لم تكن لغة أراها في كثير من الأحيان ، لذا فإنني أدهشني أن الكثير من الناس اعتادوا عليها. لأكون صادقًا ، أرى هذه الأنواع من الأخطاء المنطقية نادرًا جدًا من المطورين ذوي الخبرة ، ولهذا السبب لا أعتبرها مربكة.
وأضاف المؤلف Niklas B., مصدر
Hunter: عندما يتعلق الأمر بإنكار الارتباط والتقطيع ، فإن قوانين De Morgan مفيد جدا.
وأضاف المؤلف Niklas B., مصدر
NiklasB. مع الأخذ في الاعتبار أن النوع من الأخطاء هو أمر شائع جدًا ، سأعتبره مربكًا بما فيه الكفاية لتجنب ما يلي: ليس هناك سبب يمنعنا من تطبيق De Morgan في رأسنا في كل مرة نرى فيها ما لم يكن مع و/أو. ليس هناك فائدة أيضا لاستخدام ما لم يكن هنا.
وأضاف المؤلف Dominik Honnef, مصدر