سؤال

أنا أبحث عن طريقة موجزة للتحقق من القيمة لمعرفة ما إذا كانت صفرًا أم صفرًا.حاليًا أفعل شيئًا مثل:

if (!val || val == 0)
  # Is nil or zero
end

ولكن هذا يبدو أخرق للغاية.

هل كانت مفيدة؟

المحلول

وكائنات لها <م> لا شيء؟ طريقة .

if val.nil? || val == 0
  [do something]
end

وأو للتعليم واحد فقط:

[do something] if val.nil? || val == 0

نصائح أخرى

إذا كنت حقا مثل أسماء أسلوب مع علامات استفهام في النهاية:


if val.nil? || val.zero?
  # do stuff
end

والحل الخاص بك على ما يرام، وكذلك عدد قليل من حلول أخرى.

وروبي يمكن أن تجعلك بحث عن وسيلة جميلة لتفعل كل شيء، إذا كنت غير دقيق.

أولا أعتقد أن هذا حول الطريقة الأكثر إيجازا يمكنك التحقق من هذا الشرط معينة.

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

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

ومن روبي 2.3.0 فصاعدا، يمكنك الجمع بين المشغل الملاحة الآمنة (&.) مع <لأ href = "http://ruby-doc.org/core-2.3.0/Numeric.html#method-i- غير صفرية-3F "يختلط =" noreferrer "> Numeric#nonzero? . &. عوائد nil إذا كان المثال nil وnonzero? - إذا كان عدد 0:

unless val&.nonzero?
  # Is nil or zero
end

وأو لواحق:

do_something unless val&.nonzero?

ويمكنك استخدام Object.nil؟ لاختبار شيء على وجه التحديد (وليس ننشغل بين كاذبة ولا شيء). يمكنك القرد تصحيح طريقة إلى كائن كذلك.

class Object
   def nil_or_zero?
     return (self.nil? or self == 0)
   end
end

my_object = MyClass.new
my_object.nil_or_zero?
==> false

لا نوصي بهذه العملية كما تغييرات على كائن يصعب على زملاء العمل لتتبع، ويمكن أن تجعل التعليمات البرمجية لا يمكن التنبؤ بها للآخرين.

وأعتقد التعليمات البرمجية غير صحيح. وسوف في اختبار الواقع لثلاث قيم: nil و false ، أو والصفر. وذلك لأن التعبير !val هو الصحيح لجميع القيم التي ليست صحيحة، وهذا هو روبي nil وfalse.

وأفضل ما يمكن أن تصل في الوقت الراهن هو

if val == nil || val == 0
  # do stuff
end

والذي بالطبع ليس ذكي جدا، ولكن (جدا) واضحة.

وnil.to_i بإرجاع صفر، لذلك غالبا ما هذا:

val.to_i.zero?

ومع ذلك، سوف تحصل على استثناء إذا فال من أي وقت مضى كائن لا #to_i لا respond_to.

وبلدي الحل أيضا استخدام التحسينات، ناقص الشرطية.

module Nothingness
  refine Numeric do
    alias_method :nothing?, :zero?
  end

  refine NilClass do
    alias_method :nothing?, :nil?
  end
end

using Nothingness

if val.nothing?
  # Do something
end

والقضبان يفعل هذا عن طريق وسائل الاستعلام السمة، حيث بالإضافة إلى false وصفر (0) و "" تقييم أيضا إلى false.

if (model.attribute?) # => false if attribute is 0 and model is an ActiveRecord::Base derivation

ولكن لديها نصيبها من المنتقدين. http://www.joegrossberg.com/archives/002995.html

لكي أكون اصطلاحيًا قدر الإمكان، أقترح هذا.

if val.nil? or val == 0
    # Do something
end

لأن:

  • ويستخدم الصفر؟طريقة.
  • ويستخدم عامل التشغيل "or"، وهو أفضل من ||.
  • ولا يستخدم الأقواس، وهي ليست ضرورية في هذه الحالة.يجب استخدام الأقواس فقط عندما تخدم غرضًا ما، مثل تجاوز أسبقية عوامل تشغيل معينة.

ويجب أن تكون أقصر وأفضل طريقة

if val&.>(0)
  # do something
end

لval&.>(0) تقوم بإرجاع صفر عندما فال هو شيء منذ> في الأساس هو أيضا وسيلة، لا شيء يساوي كاذبة في روبي. أن تعيد كاذبة عندما val == 0.

وقصيرة وواضحة

و[0, nil].include?(val)

وأنا أتعامل مع هذا وذلك بتعريف "هو؟" الطريقة التي يمكنني ثم تنفيذ مختلف على مختلف الطبقات. وذلك لصفيف، "هو؟" يعني "حجم> 0". لFixnum أنها تعني "النفس = 0!". للسلسلة وهو ما يعني "النفس! = ''". NilClass، بالطبع، يعرف "هو؟" مجرد العودة لا شيء.

ويمكنك استخدام case إذا أردت:

 case val with nil, 0
      # do stuff
 end

وبعد ذلك يمكنك استخدام أي شيء أن يعمل مع ===، التي هي لطيفة في بعض الأحيان. أو تفعل شيئا من هذا القبيل:

not_valid = nil, 0
case val1 with *not_valid
      # do stuff
 end
 #do other stuff
 case val2 with *not_valid, false    #Test for values that is nil, 0 or false
      # do other other stuff
 end

وانها ليست بالضبط OOP جيد، لكنه مرن جدا، وأنه يعمل. وعادة ما تنتهي بلدي ifs على النحو cases على أي حال.

وبالطبع Enum.any? / Enum.include? نوع من يعمل أيضا ... إذا كنت ترغب في الحصول على خفي حقا:

if [0, nil].include? val
    #do stuff
end

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

وأنا حقا مثل القضبان طريقة blank? لهذا النوع من الأشياء، ولكنه لن يعود true ل0. حتى تتمكن من إضافة طريقتك:

def nil_zero? 
  if respond_to?(:zero?) 
    zero? 
  else 
    !self 
  end 
end 

وأنها سوف تحقق إذا كان بعض القيمة معدومة أو 0:

nil.nil_zero?
=> true
0.nil_zero?
=> true
10.nil_zero?
=> false

if val.nil_zero?
  #...
end

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

وهذا هو مبالغة إذا كنت تريد أن تفعل هذا الاختيار مرة واحدة، ولكن إذا كنت تكرار نفسك انها بديل كبيرة لترميم قرد.

module NilOrZero
  refine Object do
    def nil_or_zero?
      nil? or zero?
    end
  end
end

using NilOrZero
class Car
  def initialize(speed: 100)
    puts speed.nil_or_zero?
  end
end

car = Car.new              # false
car = Car.new(speed: nil)  # true
car = Car.new(speed: 0)    # true
تم تغيير

التحسينات في اللحظة الأخيرة إلى أن راقب إلى الملف. لذلك قد أظهرت الأمثلة السابقة هذه، والتي لن تعمل.

class Car
  using NilOrZero
end

وهذا هو مختصر جدا:

if (val || 0) == 0
  # Is nil, false, or zero.
end

وكان يعمل طالما كنت لا تمانع في علاج false نفس nil. في المشاريع التي عملت على، هذا التمييز الأمور مرة واحدة فقط في كل حين. باقي من الوقت وأنا شخصيا أفضل أن تخطي .nil? ولها كود أقصر قليلا.

[على تحديث : لأنا لا أكتب هذا النوع من شيء أكثر من ذلك. يعمل ولكن غير خفي جدا. لقد حاولت وضع الحق خطيئتي عن طريق تغيير الأماكن القليلة التي فعلت ذلك.]

وبالمناسبة، لم أكن استخدام .zero? منذ ذلك يثير استثناء إذا val هو، مثلا، سلسلة. ولكن سيكون .zero? غرامة إذا كنت تعرف أن هذا ليس هو الحال.

وهذا تقييم صحيح لصفر وصفر: nil.to_s.to_d == 0

unless (val || 0).zero?

    # do stufff

end

وحل آخر:

if val.to_i == 0
  # do stuff
end
val ||= 0
if val == 0
# do something here
end
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top