هل من الممكن أن يكون class.property = س عرض شيء آخر بخلاف العاشر؟

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

  •  22-08-2019
  •  | 
  •  

سؤال

ودعونا نقول لدي فئة روبي:

class MyClass
  def self.property
    return "someVal"
  end

  def self.property=(newVal)
    # do something to set "property"
    success = true

    return success # success is a boolean
  end
end

إذا كنت تحاول ان تفعل MyClass.property=x، قيمة الإرجاع للبيان كله هو دائما س. وهي الاتفاقية في الكثير من / اللغات الملهمة لإرجاع منطقية قيمة "نجاح" C المستندة - هل من الممكن القيام بذلك لاضع باستخدام "يساوي جملة" في روبي

وعلاوة على ذلك - إذا لم يكن ذلك ممكنا، لماذا لا؟ هل هناك أي سلبيات يمكن تصوره إلى السماح ل"اضع يساوي" عملية بإرجاع قيمة؟

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

المحلول

واحد السلبي هو ان كنت كسر دلالات مهمة بالسلاسل:

$ irb 
irb(main):001:0> x = y = 3
=> 3
irb(main):002:0> p x
3
=> nil
irb(main):003:0> p y
3
=> nil
irb(main):004:0> 

والنظر فيما يلي:

x = MyClass.property = 3

وبعد ذلك x سيستغرق true إذا كان هذا العمل كما كنت قد توقعت (اليمين ترابطيات). يمكن أن تكون مفاجأة للأشخاص الذين يستخدمون واجهة وتستخدم لدلالات النموذجية.

وأنت أيضا حصلت لي التفكير حول تعيين بالتوازي مع ذلك، على سبيل المثال:

x, y = 1, 2

ويبدو أن قيمة الإرجاع من هذا التعبير هو تنفيذ محددة ... اعتقد انني لن يتم تسلسل المهام متوازيين:)

والسؤال لطيف!

نصائح أخرى

ومثل يقول مارتن، وهذا من شأنه كسر مهمة تسلسل.

والطريقة التي يتم بها تعريف طرق مهمة روبي للعمل توسع MyClass.property = 3 إلى ما يعادل (lambda { |v| MyClass.send('property=', v); v })[3] (وليس حقا، ولكن هذا يظهر كيف يعمل تسلسل). قيمة الإرجاع المهمة هي دائما قيمة معينة.

إذا كنت تريد أن ترى نتيجة لطريقة MyClass#property= الخاص بك، ثم استخدم #send:

irb> o = Object.new
=> #<Object:0x15270>
irb> def o.x=(y)
irb>   @x = y+1
irb>   puts "y = #{y}, @x = #@x"
irb>   true
irb> end
=> nil
irb> def o.x
irb>   puts "@x = #@x"
irb>   @x
irb> end
=> nil
irb> o.x = 4
y = 4, @x = 5
=> 4
irb> o.x
@x = 5
=> 5
irb> o.send('x=', 3)
y = 3, @x = 4
=> true

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

# continued from above...
irb> def o.x=(y)
irb>   unless y.respond_to? :> and (y > 0 rescue false)
irb>     raise ArgumentError, 'new value must be > 0', caller
irb>   end
irb>   @x = y + 1
irb>   puts "y = #{y}, @x = #@x"
irb> end
=> nil
irb> o.x = 4
y = 4, @x = 5
=> 4
irb> o.x = 0
ArgumentError: new value must be > 0
    from (irb):12
    from :0
irb> o.x = "3"
ArgumentError: new value must be > 0
    from (irb):13
    from :0
irb> o.x
@x = 5
=> 5

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

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top