সংজ্ঞায়িত করার জন্য আপনি কীভাবে যুক্তিগুলি পাস করবেন?


155

আমি সংজ্ঞায়িত পদ্ধতি ব্যবহার করে সংজ্ঞায়িত পদ্ধতিতে একটি যুক্তি (গুলি) দিতে চাই, আমি কীভাবে এটি করব?

উত্তর:


198

আপনি যে ব্লকটিকে সংজ্ঞায়িত_মাদোবাদে পাস করেছেন তাতে কিছু প্যারামিটার অন্তর্ভুক্ত থাকতে পারে। আপনার সংজ্ঞায়িত পদ্ধতিটি এভাবেই যুক্তি গ্রহণ করে। আপনি যখন কোনও পদ্ধতিটি সংজ্ঞায়িত করেন আপনি কেবলমাত্র ব্লকটির ডাকনাম দিচ্ছেন এবং শ্রেণিতে এটির একটি রেফারেন্স রাখবেন। পরামিতিগুলি ব্লক সহ আসে। তাই:

define_method(:say_hi) { |other| puts "Hi, " + other }

ওয়েল এটি নিছক নিরপেক্ষভাবে মারার জিনিস। ভাল কাজ, কেভিন কস্টনার।
দার্ট এগারিজিয়াস

90

... এবং আপনি যদি alচ্ছিক পরামিতি চান

 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

হালনাগাদ

রুবি ২.০ ডাবল স্প্ল্যাট **(দুটি তারা) প্রবর্তন করেছে (যা আমি উদ্ধৃত করে ):

রুবি ২.০ কীওয়ার্ড আর্গুমেন্ট এবং ** * এর মতো কাজ করে তবে কীওয়ার্ড আর্গুমেন্টের জন্য introduced এটি কী / মান জোড়া দিয়ে একটি হ্যাশ প্রদান করে।

... এবং অবশ্যই আপনি এটি সংজ্ঞায়িত পদ্ধতিতেও ব্যবহার করতে পারেন :)

 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-exferences.html


আকর্ষণীয় - বিশেষত 4 র্থ ব্লক: এটি 1.8.7 এ কাজ করেছে! প্রথম ব্লকটি 1.8.7 এ কাজ করে নি, এবং দ্বিতীয় ব্লকে একটি টাইপো রয়েছে ( a.foo 1পরিবর্তে হওয়া উচিত foo 1)। এর ধন্যবাদ!
সনি সান্টোস

1
প্রতিক্রিয়ার জন্য ধন্যবাদ, টাইপো ঠিক করা হয়েছিল, ... রুবিতে 1.9.3 এবং 1.9.2 তে সমস্ত উদাহরণ কাজ করে এবং আমি ইতিবাচক যে 1.9.1 তেও (তবে চেষ্টা করিনি)
সমমান 8

রানটাইমের সময়ে কীভাবে ওভাররাইট করতে হবে (ওভাররাইড করা হবে না) এমন একটি পদ্ধতি যা alচ্ছিক আরোগুলি এবং একটি ব্লক গ্রহণ করে এবং এখনও মূল পদ্ধতিটি আরোগুলির সাহায্যে কল করতে সক্ষম হবে তা চিত্রিত করতে আমি এই উত্তরটি stackoverflow.com/questions/4470108/… এ গৃহীত উত্তরের সাথে সংযুক্ত করেছি এবং ব্লক। আহ, রুবি বিশেষত, আমি কেবল প্রোডাকশনে অ্যাক্সেস করতে পারি হোস্টের কাছে একটি একক এপিআই কল করার জন্য আমার ডেভ এনভিভিতে সাভন :: ক্লায়েন্ট.প্রভেস্ট ওভাররাইট করা দরকার। চিয়ার্স!
pduey

59

কেভিন কনারের উত্তর ছাড়াও: ব্লক আর্গুমেন্টগুলি পদ্ধতি আর্গুমেন্টের মতো একই শব্দার্থতত্ত্বকে সমর্থন করে না। আপনি ডিফল্ট আর্গুমেন্ট বা আর্গুমেন্ট ব্লক করতে পারবেন না।

এটি কেবলমাত্র রুবি ১.৯ এ নতুন বিকল্প "স্ট্যাব্বি ল্যাম্বডা" সিনট্যাক্সের সাথে স্থির করা হয়েছে যা সম্পূর্ণ পদ্ধতি আর্গুমেন্ট শব্দার্থকে সমর্থন করে।

উদাহরণ:

# 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' }

3
প্রকৃতপক্ষে, আমি বিশ্বাস করি যে সংজ্ঞায়িত ডিফলাইনগুলিতে ব্লক আর্গুমেন্টগুলি স্প্ল্যাটকে সমর্থন করে যা ডিফল্ট আর্গুমেন্টগুলিও সংজ্ঞায়িত করার জন্য একটি রাউন্ড-আ-আউটআউট উপায় সরবরাহ করতে পারে।
চিনাসৌর

1
চিনাসৌর স্প্ল্যাটগুলি অনুমোদিত ব্লক আর্গুমেন্ট সম্পর্কে সঠিক। আমি এটি রুবি 1.8.7 এবং 1.9.1 উভয়ই নিশ্চিত করেছি।
পিটার ওয়াগনেট

ধন্যবাদ, আমি এই সম্পর্কে ভুলে গেছি। এখনই স্থির।
জার্গ ডব্লু মিট্টাগ 8

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.