Soru Ruby 2.x'te adlandırılmış parametreler gerekli olabilir mi?


Ruby 2.0, şu şekilde adlandırılmış parametreler ekliyor:

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

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

Adlandırılmış parametreleri varsayılan değer vermeden nasıl kullanabilirim?


44
2017-11-06 11:52


Menşei




Cevaplar:


Ruby 2.0.0'da belirli bir yol yok, ama siz yapabilirsin Ruby 2.1.0gibi sözdizimi ile def foo(a:, b:) ...

Ruby 2.0.x'te, bir istisnayı yükselten herhangi bir ifade koyarak, bunu yapabilirsiniz.

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

Bunu çok yapmayı planlıyorsanız (ve Ruby 2.1'i kullanamazsanız), aşağıdaki gibi bir yardımcı yöntem kullanabilirsiniz:

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'

89
2018-02-25 23:55



Harika, bana burada bir şey öğrettin, teşekkürler! - Boris Stitnicky
Bunu, @Ben Taitelbaum'un cevabıyla birleştirmeyi denedim: gist.github.com/rdp/5390849 :) - rogerdpack


Şu anda (Ruby 2.0.0-preview1) aşağıdaki yöntem imzasını kullanabilirsiniz:

def say(greeting: greeting_to_say)
  puts greeting
end

greeting_to_say Adlandırılmış parametreye bir argüman sağlarsanız değerlendirilmeyecek bir yer tutucu. Eğer geçmezseniz (sadece say()), ruby ​​hatayı kaldıracaktır:

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

Bununla birlikte, bu değişken hiçbir şeye bağlı değildir ve anlayabildiğim kadarıyla, yönteminizin içinden referans alınamaz. Hala kullanırdın greeting Yerel değişken olarak adlandırılan parametre için geçirilenleri referans olarak.

Bunu gerçekten yapacak olsaydınKullanmanı öneririm def say(greeting: greeting) Böylece hata mesajı, parametrenize verdiğiniz adı referans alır. Yukarıdaki örnekte, gerekli olan parametreye bir argüman sağlamadığı için, ruby'nin kullanacağınız hata mesajında ​​ne kullanacağını göstermek için farklı örnekler seçtim.

Ara sıra, eğer ararsanız say('hi') yakut artacak ArgumentError: wrong number of arguments (1 for 0) Bence biraz kafa karıştırıcı, ama sadece önizleme1.


19
2017-11-06 11:58



Bu şık ... - awendt
Şimdi onu görüyorum, belli. Ve Ruby 2.0 ya da adlandırılmış argümanlar ile tamamen alakasız, "normal" isteğe bağlı argümanlar ile aynı şekilde çalışır ve her zaman vardır: def m(a = b) end; m # NameError: undefined local variable or method 'b' for main:Object. - Jörg W Mittag
@ JörgWMittag fantastik nokta! Bunu düşünmemiştim. - Adam
@Adam, cevabınızı biraz yanıltıcı buluyorum. Bu hataları almanızın nedeni, bir argümanın varsayılan değeri olarak rasgele Ruby koduna sahip olmanızdır. Bu, normal konumsal yayınlar için de geçerlidir ve gerekli anahtar kelime arşiviyle hiçbir ilgisi yoktur. Koymaya çalış Time.now varsayılan değer olarak ve ne olduğunu görün. Mark-Andre'nin cevabı Burada daha fazla nokta var. - Dimitar
@Dimitar Mekanizmanın net olduğunu düşündüm ve hala kullanışlı bir hata üreten eksik bir özellik etrafında güzel bir kesmek oldu. Ama ben 2.1.0-preview1 sürüm notlarını fark ettim ve Marc-Andre'nin cevabı gerçekten resmi yol olacak, bu yüzden kabul edilen cevabı değiştirdim (üzgünüm, @Adam). - Nathan Long


Çözümleri @awendt ve @Adam'dan birleştirerek,

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

Bu gibi bir şey ile DRY yapabilirsiniz:

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

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

Ve bunu Marc-Andre'nin çözümü ile birleştirerek: https://gist.github.com/rdp/5390849


11
2017-11-28 19:31



Bu özelliği geri almanın gerçekten güzel bir yolu - teşekkürler! - Nathan Long


Nasıl hakkında:

def say(greeting: nil)
  greeting or raise ArgumentError
  puts greeting
end

say                     # => raises ArgumentError
say(greeting: 'howdy')  # => puts 'howdy'

Bunun dışında, zor olacak. Göre bu site, anahtar kelime argümanları “varsayılan değerlere sahip parametreler olarak adlandırılır.”


3
2017-11-06 11:57





Ruby 2.3'te yapabilirim

def say(greeting:)
  puts greeting
end

Öyleyse kullan onu ...

say(greeting: "hello there")

1
2017-07-02 18:05