जवाबों:
जिस ब्लॉक को आप define_method में पास करते हैं, उसमें कुछ पैरामीटर शामिल हो सकते हैं। इस तरह आपकी परिभाषित पद्धति तर्कों को स्वीकार करती है। जब आप एक विधि को परिभाषित करते हैं तो आप वास्तव में केवल ब्लॉक को निनामन करते हैं और कक्षा में इसका संदर्भ रखते हैं। पैरामीटर ब्लॉक के साथ आते हैं। इसलिए:
define_method(:say_hi) { |other| puts "Hi, " + other }
... और यदि आप वैकल्पिक पैरामीटर चाहते हैं
class Bar
define_method(:foo) do |arg=nil|
arg
end
end
a = Bar.new
a.foo
#=> nil
a.foo 1
# => 1
... जितने चाहे उतने तर्क
class Bar
define_method(:foo) do |*arg|
arg
end
end
a = Bar.new
a.foo
#=> []
a.foo 1
# => [1]
a.foo 1, 2 , 'AAA'
# => [1, 2, 'AAA']
...का संयोजन
class Bar
define_method(:foo) do |bubla,*arg|
p bubla
p arg
end
end
a = Bar.new
a.foo
#=> wrong number of arguments (0 for 1)
a.foo 1
# 1
# []
a.foo 1, 2 ,3 ,4
# 1
# [2,3,4]
... उन सभी को
class Bar
define_method(:foo) do |variable1, variable2,*arg, &block|
p variable1
p variable2
p arg
p block.inspect
end
end
a = Bar.new
a.foo :one, 'two', :three, 4, 5 do
'six'
end
अपडेट करें
रूबी 2.0 ने डबल स्पैट **
(दो स्टार) पेश किए, जो ( मैं बोली ) करता है:
रूबी 2.0 ने खोजशब्द तर्क प्रस्तुत किए, और ** कार्य * की तरह, लेकिन खोजशब्द तर्क के लिए। यह कुंजी / मान जोड़े के साथ एक हैश लौटाता है।
... और निश्चित रूप से आप इसे परिभाषित विधि में भी उपयोग कर सकते हैं :)
class Bar
define_method(:foo) do |variable1, variable2,*arg,**options, &block|
p variable1
p variable2
p arg
p options
p block.inspect
end
end
a = Bar.new
a.foo :one, 'two', :three, 4, 5, ruby: 'is awesome', foo: :bar do
'six'
end
# :one
# "two"
# [:three, 4, 5]
# {:ruby=>"is awesome", :foo=>:bar}
नामित विशेषताएँ उदाहरण:
class Bar
define_method(:foo) do |variable1, color: 'blue', **other_options, &block|
p variable1
p color
p other_options
p block.inspect
end
end
a = Bar.new
a.foo :one, color: 'red', ruby: 'is awesome', foo: :bar do
'six'
end
# :one
# "red"
# {:ruby=>"is awesome", :foo=>:bar}
मैं सभी में एक साथ कीवर्ड तर्क, बवंडर और डबल स्पैट के साथ उदाहरण बनाने की कोशिश कर रहा था:
define_method(:foo) do |variable1, variable2,*arg, i_will_not: 'work', **options, &block|
# ...
या
define_method(:foo) do |variable1, variable2, i_will_not: 'work', *arg, **options, &block|
# ...
... लेकिन यह काम नहीं करेगा, ऐसा लगता है कि एक सीमा है। जब आप इसके बारे में सोचते हैं तो यह समझ में आता है कि स्पैट ऑपरेटर "सभी शेष तर्कों को कैप्चर कर रहा है" और डबल स्पैट "सभी शेष तर्कों को कैप्चर कर रहा है" इसलिए उन्हें मिश्रण करना अपेक्षित तर्क को तोड़ देगा। (मेरे पास इस बिंदु को साबित करने के लिए कोई संदर्भ नहीं है!)
अपडेट 2018 अगस्त:
सारांश लेख: https://blog.eq8.eu/til/metaprogramming-ruby-examples.html
a.foo 1
इसके बजाय होना चाहिए foo 1
) है। धन्यवाद!
केविन कोनर के जवाब के अलावा: ब्लॉक तर्क पद्धति के तर्कों के समान शब्दार्थ का समर्थन नहीं करते हैं। आप डिफ़ॉल्ट तर्क या ब्लॉक तर्क को परिभाषित नहीं कर सकते।
यह केवल रूबी 1.9 में नए वैकल्पिक "स्टैबी लैम्ब्डा" सिंटैक्स के साथ तय किया गया है जो पूर्ण विधि तर्क शब्दार्थ का समर्थन करता है।
उदाहरण:
# Works
def meth(default = :foo, *splat, &block) puts 'Bar'; end
# Doesn't work
define_method :meth { |default = :foo, *splat, &block| puts 'Bar' }
# This works in Ruby 1.9 (modulo typos, I don't actually have it installed)
define_method :meth, ->(default = :foo, *splat, &block) { puts 'Bar' }
2.2 के साथ अब आप कीवर्ड तर्कों का उपयोग कर सकते हैं: https://robots.thoughtbot.com/ruby-2-keyword-arguments
define_method(:method) do |refresh: false|
..........
end