खोज…


परिचय

रूबी में कार्य संगठित, पुन: प्रयोज्य कोड प्रदान करते हैं जो क्रियाओं के एक सेट को बेहतर बनाते हैं। फ़ंक्शंस कोडिंग प्रक्रिया को सरल करते हैं, अनावश्यक तर्क को रोकते हैं, और कोड का पालन करना आसान बनाते हैं। यह विषय रूबी में कार्यों, तर्कों, मापदंडों, उपज बयानों और गुंजाइश की घोषणा और उपयोग का वर्णन करता है।

टिप्पणियों

एक विधि कोड का एक नामित ब्लॉक है, जो एक या एक से अधिक वस्तुओं से जुड़ा होता है और आमतौर पर नाम के अतिरिक्त मापदंडों की एक सूची द्वारा पहचाना जाता है।

def hello(name)
  "Hello, #{name}"
end

एक विधि मंगलाचरण विधि नाम को निर्दिष्ट करता है, जिस ऑब्जेक्ट पर इसे लागू किया जाना है (कभी-कभी रिसीवर कहा जाता है), और शून्य या अधिक तर्क मान जिन्हें नामित विधि मापदंडों को सौंपा गया है। विधि में मूल्यांकन की गई अंतिम अभिव्यक्ति का मूल्य विधि मंगलाचरण अभिव्यक्ति का मूल्य बन जाता है।

hello("World")
# => "Hello, World"

जब रिसीवर स्पष्ट नहीं है, तो यह self

self
# => main

self.hello("World")
# => "Hello, World"

जैसा कि रूबी प्रोग्रामिंग लैंग्वेज बुक में बताया गया है, कई भाषाएँ फ़ंक्शंस के बीच अंतर करती हैं, जिसमें कोई संबंधित ऑब्जेक्ट नहीं होता है, और तरीके, जो एक रिसीवर ऑब्जेक्ट पर लगाए जाते हैं। क्योंकि रूबी एक विशुद्ध रूप से ऑब्जेक्ट-ओरिएंटेड भाषा है, सभी विधियाँ सही तरीके हैं और कम से कम एक ऑब्जेक्ट से जुड़ी हैं।

विधि पैरामीटर्स का अवलोकन

प्रकार विधि हस्ताक्षर कॉल उदाहरण कार्य
आर ने बराबरी की def fn(a,b,c) fn(2,3,5) a=2, b=3, c=5
वी ariadic def fn(*rest) fn(2,3,5) rest=[2, 3, 5]
डी efault def fn(a=0,b=1) fn(2,3) a=2, b=3
K आँख def fn(a:0,b:1) fn(a:2,b:3) a=2, b=3

इन तर्क प्रकारों को वस्तुतः किसी भी तरह से जोड़ा जा सकता है जिसे आप वैरेडिक फ़ंक्शंस बनाने के लिए कल्पना कर सकते हैं। फ़ंक्शन में तर्कों की न्यूनतम संख्या हस्ताक्षर में आवश्यक तर्कों की मात्रा के बराबर होगी। अतिरिक्त तर्कों को पहले डिफ़ॉल्ट मापदंडों को सौंपा जाएगा, फिर *rest पैरामीटर को।

प्रकार विधि हस्ताक्षर कॉल उदाहरण कार्य
आर, डी, वी, आर def fn(a,b=1,*mid,z) fn(2,97) a=2, b=1, mid=[], z=97
fn(2,3,97) a=2, b=3, mid=[], z=97
fn(2,3,5,97) a=2, b=3, mid=[5], z=97
fn(2,3,5,7,97) a=2, b=3, mid=[5,7], z=97
आर, कश्मीर, कश्मीर def fn(a,g:6,h:7) fn(2) a=2, g=6, h=7
fn(2,h:19) a=2, g=6, h=19
fn(2,g:17,h:19) a=2, g=17, h=19
वीके def fn(**ks) fn(a:2,g:17,h:19) ks={a:2, g:17, h:19}
fn(four:4,five:5) ks={four:4, five:5}

एकल आवश्यक पैरामीटर

def say_hello_to(name)
    puts "Hello #{name}"
end

say_hello_to('Charles')    # Hello Charles

एकाधिक आवश्यक पैरामीटर

def greet(greeting, name)
    puts "#{greeting} #{name}"
end

greet('Hi', 'Sophie')    # Hi Sophie

डिफ़ॉल्ट पैरामीटर

def make_animal_sound(sound = 'Cuack')
    puts sound
end

make_animal_sound('Mooo') # Mooo
make_animal_sound         # Cuack

कई तर्कों के लिए चूक को शामिल करना संभव है:

def make_animal_sound(sound = 'Cuack', volume = 11)
    play_sound(sound, volume)
end

make_animal_sound('Mooo') # Spinal Tap cow

हालांकि, पहले की आपूर्ति के बिना दूसरे की आपूर्ति करना संभव नहीं है। स्थितिगत मापदंडों का उपयोग करने के बजाय, कीवर्ड पैरामीटर आज़माएं:

def make_animal_sound(sound: 'Cuack', volume: 11)
    play_sound(sound, volume)
end

make_animal_sound(volume: 1) # Duck whisper

या एक हैश पैरामीटर जो विकल्पों को संग्रहीत करता है:

def make_animal_sound(options = {})
    options[:sound]  ||= 'Cuak'
    options[:volume] ||= 11
    play_sound(sound, volume)
end

make_animal_sound(:sound => 'Mooo') 

डिफ़ॉल्ट पैरामीटर मान किसी भी रूबी अभिव्यक्ति द्वारा निर्धारित किए जा सकते हैं। अभिव्यक्ति विधि के संदर्भ में चलेगी, इसलिए आप यहां स्थानीय चर भी घोषित कर सकते हैं। नोट, कोड समीक्षा के माध्यम से नहीं मिलेगा। इसे इंगित करने के लिए कैयस के सौजन्य से

def make_animal_sound( sound = ( raise 'TUU-too-TUU-too...' ) ); p sound; end

make_animal_sound 'blaaaa' # => 'blaaaa'
make_animal_sound          # => TUU-too-TUU-too... (RuntimeError)

वैकल्पिक पैरामीटर (स्पैट ऑपरेटर)

def welcome_guests(*guests)
    guests.each { |guest| puts "Welcome #{guest}!" }
end

welcome_guests('Tom')    # Welcome Tom!
welcome_guests('Rob', 'Sally', 'Lucas') # Welcome Rob!
                                        # Welcome Sally!
                                        # Welcome Lucas!

ध्यान दें कि welcome_guests(['Rob', 'Sally', 'Lucas']) Welcome ["Rob", "Sally", "Lucas"]! उत्पादन करेगा Welcome ["Rob", "Sally", "Lucas"]!
इसके बजाय, यदि आपके पास एक सूची है, तो आप welcome_guests(*['Rob', 'Sally', 'Lucas']) और यह welcome_guests('Rob', 'Sally', 'Lucas') रूप में काम करेगा।

आवश्यक डिफ़ॉल्ट वैकल्पिक पैरामीटर मिश्रण

def my_mix(name,valid=true, *opt)
    puts name
    puts valid
    puts opt
end

कॉल इस प्रकार है:

my_mix('me')
# 'me'
# true
# []

my_mix('me', false)
# 'me'
# false
# []

my_mix('me', true, 5, 7) 
# 'me'
# true
# [5,7]

विधि परिभाषाएँ अभिव्यक्तियाँ हैं

रूबी 2.x में एक विधि को परिभाषित करते हुए नाम का प्रतिनिधित्व करने वाला एक प्रतीक देता है:

class Example
  puts def hello
  end
end

#=> :hello

यह दिलचस्प मेटाप्रोग्रामिंग तकनीकों के लिए अनुमति देता है। उदाहरण के लिए, तरीकों को अन्य तरीकों से लपेटा जा सकता है:

class Class
  def logged(name)
    original_method = instance_method(name)
    define_method(name) do |*args|
      puts "Calling #{name} with #{args.inspect}."
      original_method.bind(self).call(*args)
      puts "Completed #{name}."
    end
  end
end

class Meal
  def initialize
    @food = []
  end
  
  logged def add(item)
    @food << item
  end
end

meal = Meal.new
meal.add "Coffee"
# Calling add with ["Coffee"].
# Completed add.

अघोषित खोजशब्द तर्कों (डबल छप) को पकड़ना

** ऑपरेटर की तरह ही काम करता है * ऑपरेटर लेकिन यह कीवर्ड मापदंडों पर लागू होता है।

def options(required_key:, optional_key: nil, **other_options)
  other_options
end

options(required_key: 'Done!', foo: 'Foo!', bar: 'Bar!')
#> { :foo => "Foo!", :bar => "Bar!" }

उपर्युक्त उदाहरण में, यदि **other_options का उपयोग नहीं किया गया है, तो एक ArgumentError: unknown keyword: foo, bar त्रुटि उठाई जाएगी।

def without_double_splat(required_key:, optional_key: nil)
  # do nothing
end

without_double_splat(required_key: 'Done!', foo: 'Foo!', bar: 'Bar!')
#> ArgumentError: unknown keywords: foo, bar

यह तब आसान होता है जब आपके पास विकल्पों का एक हैश होता है जिसे आप एक विधि में पास करना चाहते हैं और आप कुंजियों को फ़िल्टर नहीं करना चाहते हैं।

def options(required_key:, optional_key: nil, **other_options)
  other_options
end

my_hash = { required_key: true, foo: 'Foo!', bar: 'Bar!' }

options(my_hash)
#> { :foo => "Foo!", :bar => "Bar!" }

** ऑपरेटर का उपयोग करके हैश को अनपैक करना भी संभव है। यह आपको अन्य हैश के मानों के अलावा सीधे कीवर्ड को एक विधि से आपूर्ति करने की अनुमति देता है:

my_hash = { foo: 'Foo!', bar: 'Bar!' }

options(required_key: true, **my_hash)
#> { :foo => "Foo!", :bar => "Bar!" }

खेतों में उपज

आप अपने तरीके से एक ब्लॉक भेज सकते हैं और यह उस ब्लॉक को कई बार कॉल कर सकता है। यह एक खरीद / लंबो या ऐसा भेजकर किया जा सकता है, लेकिन yield साथ आसान और तेज yield :

def simple(arg1,arg2)
  puts "First we are here:  #{arg1}"
  yield
  puts "Finally we are here:  #{arg2}"
  yield
end
simple('start','end') { puts "Now we are inside the yield" }

#> First we are here:  start
#> Now we are inside the yield
#> Finally we are here:  end
#> Now we are inside the yield

ध्यान दें कि { puts ... } कोष्ठकों के अंदर नहीं है, यह बाद में आता है। इसका मतलब यह भी है कि हमारे पास केवल एक yield ब्लॉक हो सकता है। हम yield लिए तर्क पारित कर सकते हैं:

def simple(arg)
  puts "Before yield"
  yield(arg)
  puts "After yield"
end
simple('Dave') { |name| puts "My name is #{name}" }

#> Before yield
#> My name is Dave
#> After yield

उपज के साथ हम आसानी से पुनरावृत्तियों या किसी भी कार्य को कर सकते हैं जो अन्य कोड पर काम करता है:

def countdown(num)
  num.times do |i|
    yield(num-i)
  end
end

countdown(5) { |i| puts "Call number #{i}" }

#> Call number 5
#> Call number 4
#> Call number 3
#> Call number 2
#> Call number 1

वास्तव में, यह साथ है yield है कि तरह बातें foreach , each और times आम तौर पर कक्षाओं में लागू किया जाता है।

यदि आप यह जानना चाहते हैं कि आपको ब्लॉक दिया गया है या नहीं, तो block_given? उपयोग block_given? :

class Employees
  def names
    ret = []
    @employees.each do |emp|
      if block_given?
        yield(emp.name)
      else
        ret.push(emp.name) 
      end
    end

    ret
  end
end

यह उदाहरण मानता है कि Employees वर्ग के पास एक @employees सूची है जिसे each साथ पुनरावृत्त किया जा सकता है ताकि उन वस्तुओं को प्राप्त किया जा सके जिनके name पद्धति का उपयोग करके कर्मचारी नाम हैं। हम एक ब्लॉक दिया जाता है, तो हम करेंगे yield नाम ब्लॉक करने के लिए, नहीं तो हम सिर्फ एक सरणी के लिए धक्का है कि हम वापसी।

टपल तर्क

एक विधि एक सरणी पैरामीटर ले सकती है और इसे नामांकित स्थानीय चर में तुरंत नष्ट कर सकती है। माथियास मेयर के ब्लॉग पर मिला।

def feed( amount, (animal, food) )

    p "#{amount} #{animal}s chew some #{food}"

end

feed 3, [ 'rabbit', 'grass' ] # => "3 rabbits chew some grass"

एक विधि परिभाषित करना

तरीकों के साथ परिभाषित कर रहे हैं def , कीवर्ड विधि नाम और कोष्ठक में पैरामीटर नामों में से एक वैकल्पिक सूची के द्वारा पीछा किया। def एंड end के बीच रूबी कोड विधि के शरीर का प्रतिनिधित्व करता है

def hello(name)
  "Hello, #{name}"
end

एक विधि मंगलाचरण विधि नाम को निर्दिष्ट करता है, जिस ऑब्जेक्ट पर इसे लागू किया जाना है (कभी-कभी रिसीवर कहा जाता है), और शून्य या अधिक तर्क मान जिन्हें नामित विधि मापदंडों को सौंपा गया है।

hello("World")
# => "Hello, World"

जब रिसीवर स्पष्ट नहीं है, तो यह self

पैरामीटर नामों का उपयोग विधि निकाय के भीतर चर के रूप में किया जा सकता है, और इन नामित मापदंडों के मूल्य तर्क से एक विधि आह्वान तक आते हैं।

hello("World")
# => "Hello, World"
hello("All")
# => "Hello, All"

एक ब्लॉक के रूप में एक फ़ंक्शन का उपयोग करें

रूबी में कई कार्य एक ब्लॉक को एक तर्क के रूप में स्वीकार करते हैं। उदाहरण के लिए:

[0, 1, 2].map {|i| i + 1}
 => [1, 2, 3]

यदि आपके पास पहले से ही कोई फ़ंक्शन है जो आप चाहते हैं, तो आप इसे &method(:fn) का उपयोग करके ब्लॉक में बदल सकते हैं:

def inc(num)
   num + 1
end

[0, 1, 2].map &method(:inc)
 => [1, 2, 3]


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow