ruby - هل يمكنني طلب المعلمات المسماة في روبي 2.x؟




arguments ruby-2.0 (4)

يضيف روبي 2.0 المعلمات المسماة ، مثل هذا:

def say(greeting: 'hi')
  puts greeting
end

say                     # => puts 'hi'
say(greeting: 'howdy')  # => puts 'howdy'

كيف يمكنني استخدام المعلمات المسماة دون إعطاء قيمة افتراضية ، بحيث تكون مطلوبة؟


في الوقت الحالي (روبي 2.0.0- معاينة 1) ، يمكنك استخدام توقيع الطريقة التالية:

def say(greeting: greeting_to_say)
  puts greeting
end

greeting_to_say هو مجرد عنصر نائب لن يتم تقييمه إذا قمت بتوفير وسيطة للمعلمة المسماة. إذا لم تقم بتمريرها (استدعاء فقط say() ) ، فسوف يثير روبي الخطأ:

NameError: undefined local variable or method `greeting_to_say' for (your scope)

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

إذا كنت ستقوم بذلك فعلاً ، فإنني أوصي باستخدام def say(greeting: greeting) بحيث تشير رسالة الخطأ إلى الاسم الذي تعطيه للمعلمة الخاصة بك. لقد اخترت فقط عناصر مختلفة في المثال أعلاه لتوضيح ما سيستخدمه روبي في رسالة الخطأ التي تحصل عليها لعدم تقديم وسيطة للمعلمة المسماة المطلوبة.

بشكل عرضي ، إذا اتصلت ، say('hi') روبي say('hi') سيرفع ArgumentError: wrong number of arguments (1 for 0) والذي أعتقد أنه مربك بعض الشيء ، لكنه معاينة فقط 1.


في روبي 2.3 ، يمكنني القيام به

def say(greeting:)
  puts greeting
end

ثم استخدمه مع ...

say(greeting: "hello there")

لا توجد طريقة محددة في روبي 2.0.0 ، ولكن يمكنك القيام بذلك روبي 2.1.0 ، مع بناء جملة مثل def foo(a:, b:) ...

في Ruby 2.0.x ، يمكنك فرضه عن طريق وضع أي تعبير يثير استثناءً ، على سبيل المثال:

def say(greeting: raise "greeting is required")
  # ...
end

إذا كنت تخطط للقيام بهذا كثيرًا (ولا يمكنك استخدام Ruby 2.1+) ، فيمكنك استخدام طريقة مساعدة مثل:

def required
  method = caller_locations(1,1)[0].label
  raise ArgumentError,
    "A required keyword argument was not specified when calling '#{method}'"
end

def say(greeting: required)
  # ...
end

say # => A required keyword argument was not specified when calling 'say'

يجمع بين الحلول منawendt وAdam ،

def say(greeting: ->{ raise ArgumentError.new("greeting is required") }.call)
  puts greeting
end

يمكنك تجفيف ذلك باستخدام شيء مثل:

def required(arg)
  raise ArgumentError.new("required #{arg}")
end

def say(greeting: required('greeting'))
  puts greeting
end

ودمج ذلك مع حل @ Marc-Andre: gist.github.com/rdp/5390849





ruby-2.1