ट्रैक
/
Ruby
Ruby
/
सिलेबस
/
मल्टीपल असाइनमेंट और डीकंपोज़िशन
मल

मल्टीपल असाइनमेंट और डीकंपोज़िशन में Ruby

1 अभ्यास

मल्टीपल असाइनमेंट और डीकंपोज़िशन के बारे में

डीकंपोज़िशन का मतलब है किसी कलेक्शन, जैसे Array या Hash, के एलिमेंट अलग-अलग निकालना। इस तरह अलग की गई वैल्यू को उसी स्टेटमेंट में वेरिएबलो को असाइन किया जा सकता है।

मल्टीपल असाइनमेंट एक ही स्टेटमेंट में कई वेरिएबलो को वैल्यू असाइन करने की सुविधा है। इससे कोड ज़्यादा छोटा और पढ़ने में आसान हो जाता है। इसके लिए जिन वेरिएबलो को असाइन करना है, उन्हें कॉमा से अलग किया जाता है, जैसे first, second, third = [1, 2, 3]।

स्प्लैट ऑपरेटर (*) और डबल स्प्लैट ऑपरेटर (**) का इस्तेमाल अक्सर डीकंपोज़िशन में होता है। स्प्लैट ऑपरेटर (*) की मदद से कई ऐरे को मिलाकर एक ऐरे बनाया जा सकता है; इसके लिए हर ऐरे को डीकंपोज़ करके एक नए साझा ऐरे में रखा जाता है। डबल स्प्लैट ऑपरेटर (**) की मदद से कई डिक्शनरी को मिलाकर एक डिक्शनरी बनाई जा सकती है; इसके लिए हर डिक्शनरी को डीकंपोज़ करके एक नई साझा डिक्शनरी में रखा जाता है। यह सिंटैक्स इस फ़र्क को साफ़ करता है: कहीं हम पोज़िशनल आर्गुमेंट के रूप में कई वैल्यू लेते हैं, तो कहीं कितने भी कीवर्ड आर्गुमेंट लेते हैं।

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

Ruby में ऐसे मेथड बनाते या इस्तेमाल करते समय यह डीकंपोज़/कंपोज़ करने वाला व्यवहार आम है जो कितने भी पोज़िशनल या कीवर्ड आर्गुमेंट लेते हैं। आप अक्सर देखेंगे कि ऐसे आर्गुमेंट def some_method(*arguments, **keyword_arguments) की तरह परिभाषित किए जाते हैं और some_method(*some_array, **some_hash) की तरह इस्तेमाल किए जाते हैं।

Caution

*<variable_name> और **<variable_name> को * और ** से भ्रमित नहीं किया जाना चाहिए। जहाँ * और ** क्रमशः गुणा और घात के लिए इस्तेमाल होते हैं, वहीं *<variable_name> और **<variable_name> कंपोज़िशन और डीकंपोज़िशन ऑपरेटर के रूप में इस्तेमाल होते हैं।

मल्टीपल असाइनमेंट

मल्टीपल असाइनमेंट से आप एक ही लाइन में कई वेरिएबलो को वैल्यू असाइन कर सकते हैं। वैल्यू को अलग करने के लिए कॉमा , लगाइए:

>> a, b = 1, 2
=> [1, 2]
>> a
=> 1

मल्टीपल असाइनमेंट किसी एक डेटा टाइप तक सीमित नहीं है:

>> x, y, z = 1, "Hello", true
=> [1, "Hello", true]
>> x
=> 1
>> y
=> 'Hello'
>> z
=> true

मल्टीपल असाइनमेंट का इस्तेमाल ऐरे के एलिमेंट आपस में बदलने के लिए किया जा सकता है। सॉर्टिंग एल्गोरिदम में यह तरीका काफी आम है। उदाहरण के लिए:

>> numbers = [1, 2]
=> [1, 2]
>> numbers[0], numbers[1] = numbers[1], numbers[0]
=> [2, 1]
>> numbers
=> [2, 1]
Note

इसे "पैरेलल असाइनमेंट" भी कहा जाता है, और इसका इस्तेमाल एक अस्थायी वेरिएबल से बचने के लिए किया जा सकता है।

अगर वैल्यू से ज़्यादा वेरिएबल हों, तो अतिरिक्त वेरिएबलो को nil असाइन किया जाता है:

>> a, b, c = 1, 2
=> [1, 2]
>> b
=> 2
>> c
=> nil

अगर वेरिएबल से ज़्यादा वैल्यू हों, तो अतिरिक्त वैल्यू छोड़ दी जाती हैं:

>> a, b, c = 1, 2, 3, 4
>> b
=> 2
>> c
=> 3

डीकंपोज़िशन

Ruby में ऐरे/डिक्शनरी के एलिमेंट को अलग-अलग वेरिएबलो में डीकंपोज़ किया जा सकता है। चूँकि ऐरे में वैल्यू इंडेक्स क्रम में रहती हैं, इसलिए उन्हें भी उसी क्रम में वेरिएबलो में खोला जाता है:

>> fruits = ["apple", "banana", "cherry"]
>> x, y, z = fruits
>> x
=> "apple"

अगर कुछ वैल्यू की ज़रूरत नहीं है, तो _ लगाकर बता सकते हैं कि उन्हें इकट्ठा तो किया गया है, पर इस्तेमाल नहीं किया जाएगा:

>> fruits = ["apple", "banana", "cherry"]
>> _, _, z = fruits
>> z
=> "cherry"

गहराई तक डीकंपोज़ करना

किसी ऐरे के अंदर मौजूद ऐरे (जिसे नेस्टेड ऐरे भी कहते हैं) से वैल्यू डीकंपोज़ करके असाइन करना सतही डीकंपोज़िशन की तरह ही काम करता है, लेकिन वैल्यू का संदर्भ या स्थान साफ़ करने के लिए इसमें सीमांकित डीकंपोज़िशन एक्सप्रेशन (()) की ज़रूरत पड़ती है:

>> fruits_vegetables = [["apple", "banana"], ["carrot", "potato"]]
>> (a, b), (c, d) = fruits_vegetables
>> a
=> "apple"
>> d
=> "potato"

आप किसी नेस्टेड ऐरे के सिर्फ एक हिस्से को भी गहराई तक खोल सकते हैं:

>> fruits_vegetables = [["apple", "banana"], ["carrot", "potato"]]
>> a, (c, d) = fruits_vegetables
>> a
=> ["apple", "banana"]
>> c
=> "carrot"

अगर डीकंपोज़िशन में वेरिएबलो की जगह गलत हो या वैल्यू की संख्या गलत हो, तो आपको सिंटैक्स एरर मिलेगी:

fruits_vegetables = [["apple", "banana"], ["carrot", "potato"]]
(a, b), (d) = fruits_vegetables

syntax error, unexpected ')', expecting '.' or &. or :: or '['
((a, b), (d)) = fruits_vegetables

यहाँ प्रयोग करके देखिए, आप पाएँगे कि तय पहला पैटर्न करता है, दाईं ओर की उपलब्ध वैल्यू नहीं। यह सिंटैक्स एरर डेटा स्ट्रक्चर से जुड़ी नहीं है।

सिंगल स्प्लैट ऑपरेटर (*) से ऐरे को डीकंपोज़ करना

किसी ऐरे को [डीकंपोज़ करते समय][decomposition] आप स्प्लैट ऑपरेटर (*) से बची हुई वैल्यू पकड़ सकते हैं। यह ऐरे को स्लाइस करने से ज़्यादा साफ़ है (जो कुछ स्थितियों में कम पढ़ने योग्य होता है)। उदाहरण के लिए, हम पहला एलिमेंट निकाल सकते हैं और बाकी वैल्यू को पहले एलिमेंट के बिना एक नए ऐरे में असाइन कर सकते हैं:

>> fruits = ["apple", "banana", "cherry", "orange", "kiwi", "melon", "mango"]
>> x, *last = fruits
>> x
=> "apple"
>> last
=> ["banana", "cherry", "orange", "kiwi", "melon", "mango"]

हम ऐरे के शुरू और अंत की वैल्यू निकालकर बीच की सारी वैल्यू को एक साथ भी रख सकते हैं:

>> fruits = ["apple", "banana", "cherry", "orange", "kiwi", "melon", "mango"]
>> x, *middle, y, z = fruits
>> y
=> "melon"
>> middle
=> ["banana", "cherry", "orange", "kiwi"]

गहरे डीकंपोज़िशन में भी * का इस्तेमाल किया जा सकता है:

>> fruits_vegetables = [["apple", "banana", "melon"], ["carrot", "potato", "tomato"]]
>> (a, *rest), b = fruits_vegetables
>> a
=> "apple"
>> rest
=> ["banana", "melon"]

Hash को डीकंपोज़ करना

डिक्शनरी को डीकंपोज़ करना ऐरे को डीकंपोज़ करने से थोड़ा अलग है। डिक्शनरी को खोलने के लिए पहले उसे ऐरे में बदलना पड़ता है। ऐसा न करने पर डीकंपोज़िशन नहीं होगा:

>> fruits_inventory = {apple: 6, banana: 2, cherry: 3}
>> x, y, z = fruits_inventory
>> x
=> {:apple=>6, :banana=>2, :cherry=>3}
>> y
=> nil

किसी Hash को ऐरे में बदलने के लिए आप to_a मेथड इस्तेमाल कर सकते हैं:

>> fruits_inventory = {apple: 6, banana: 2, cherry: 3}
>> fruits_inventory.to_a
=> [[:apple, 6], [:banana, 2], [:cherry, 3]]
>> x, y, z = fruits_inventory.to_a
>> x
=> [:apple, 6]

अगर आप हैश में मौजूद की खोलना चाहते हैं, तो keys मेथड इस्तेमाल कीजिए:

>> fruits_inventory = {apple: 6, banana: 2, cherry: 3}
>> x, y, z = fruits_inventory.keys
>> x
=> :apple

अगर आप हैश में मौजूद वैल्यू खोलना चाहते हैं, तो values मेथड इस्तेमाल कीजिए:

>> fruits_inventory = {apple: 6, banana: 2, cherry: 3}
>> x, y, z = fruits_inventory.values
>> x
=> 6

कंपोज़िशन

कंपोज़ करने का मतलब है कई वैल्यू को एक ऐरे में इकट्ठा करके किसी वेरिएबल को सौंपना। यह तब काम आता है जब आप वैल्यू को डीकंपोज़ करना, उनमें बदलाव करना और फिर नतीजों को कंपोज़ करके वापस एक वेरिएबल में रखना चाहते हैं। इससे दो या अधिक ऐरे/डिक्शनरी पर मर्ज करना भी संभव हो जाता है।

स्प्लैट ऑपरेटर (*) से ऐरे का कंपोज़िशन

किसी ऐरे को स्प्लैट ऑपरेटर (*) से कंपोज़ किया जा सकता है। यह सारी वैल्यू को एक ऐरे में पैक कर देता है।

>> fruits = ["apple", "banana", "cherry"]
>> more_fruits = ["orange", "kiwi", "melon", "mango"]

# fruits and more_fruits are unpacked and then their elements are packed into combined_fruits
>> combined_fruits = *fruits, *more_fruits

>> combined_fruits
=> ["apple", "banana", "cherry", "orange", "kiwi", "melon", "mango"]

डबल स्प्लैट ऑपरेटर (**) से हैश का कंपोज़िशन

हैश को डबल स्प्लैट ऑपरेटर (**) से कंपोज़ किया जाता है। यह एक हैश के सारे की/वैल्यू जोड़े दूसरे हैश में पैक कर देता है, या दो हैश को आपस में मिला देता है।

>> fruits_inventory = {apple: 6, banana: 2, cherry: 3}
>> more_fruits_inventory = {orange: 4, kiwi: 1, melon: 2, mango: 3}

# fruits_inventory and more_fruits_inventory are unpacked into key-values pairs and combined.
>> combined_fruits_inventory = {**fruits_inventory, **more_fruits_inventory}

# then the pairs are packed into combined_fruits_inventory
>> combined_fruits_inventory
=> {:apple=>6, :banana=>2, :cherry=>3, :orange=>4, :kiwi=>1, :melon=>2, :mango=>3}

मेथड के साथ स्प्लैट ऑपरेटर (*) और डबल स्प्लैट ऑपरेटर (**) का इस्तेमाल

मेथड पैरामीटर के साथ कंपोज़िशन

जब आप ऐसा मेथड बनाते हैं जो कितने भी आर्गुमेंट ले सकता है, तो मेथड की परिभाषा में *arguments या **keyword_arguments इस्तेमाल कर सकते हैं। *arguments कितने भी पोज़िशनल (गैर-कीवर्ड) आर्गुमेंट को पैक करने के लिए इस्तेमाल होता है और **keyword_arguments कितने भी कीवर्ड आर्गुमेंट को पैक करने के लिए।

*arguments का इस्तेमाल:

# This method is defined to take any number of positional arguments
# (Using the single line form of the definition of a method.)

>> def my_method(*arguments)= arguments

# Arguments given to the method are packed into an array

>> my_method(1, 2, 3)
=> [1, 2, 3]

>> my_method("Hello")
=> ["Hello"]

>> my_method(1, 2, 3, "Hello", "Mars")
=> [1, 2, 3, "Hello", "Mars"]

**keyword_arguments का इस्तेमाल:

# This method is defined to take any number of keyword arguments

>> def my_method(**keyword_arguments)= keyword_arguments

# Arguments given to the method are packed into a dictionary

>> my_method(a: 1, b: 2, c: 3)
=> {:a => 1, :b => 2, :c => 3}

अगर बनाए गए मेथड में कीवर्ड आर्गुमेंट के लिए कोई पैरामीटर तय नहीं है (**keyword_arguments या <key_word>: <value>), तो कीवर्ड आर्गुमेंट एक हैश में पैक होकर अंतिम पैरामीटर को असाइन कर दिए जाते हैं।

>> def my_method(a)= a

>> my_method(a: 1, b: 2, c: 3)
=> {:a => 1, :b => 2, :c => 3}

*arguments और **keyword_arguments को एक साथ मिलाकर भी इस्तेमाल किया जा सकता है:

def my_method(*arguments, **keyword_arguments)
  p arguments.sum
  for (key, value) in keyword_arguments.to_a
    p key.to_s + " = " + value.to_s
  end
end


my_method(1, 2, 3, a: 1, b: 2, c: 3)
6
"a = 1"
"b = 2"
"c = 3"

आप *arguments से पहले और बाद में भी आर्गुमेंट लिख सकते हैं, ताकि कुछ खास पोज़िशनल आर्गुमेंट तय किए जा सकें। यह ऐरे को डीकंपोज़ करने की तरह ही काम करता है।

Caution

आर्गुमेंट को एक तय क्रम में ही लिखा जाना चाहिए:

def my_method(<positional_arguments>, *arguments, <positional_arguments>, <key-word_arguments>, **keyword_arguments)

अगर आप इस क्रम का पालन नहीं करते, तो आपको एरर मिलेगी।

def my_method(a, b, *arguments)
  p a
  p b
  p arguments
end

my_method(1, 2, 3, 4, 5)
1
2
[3, 4, 5]

आप *arguments से पहले और बाद में पोज़िशनल आर्गुमेंट लिख सकते हैं:

>> def my_method(a, *middle, b)= middle

>> my_method(1, 2, 3, 4, 5)
=> [2, 3, 4]

आप पोज़िशनल आर्गुमेंट, *arguments, कीवर्ड आर्गुमेंट और **keyword_arguments को भी एक साथ मिला सकते हैं:

>> def my_method(first, *many, last, a:, **keyword_arguments)
     p first
     p many
     p last
     p a
     p keyword_arguments
     end

>> my_method(1, 2, 3, 4, 5, a: 6, b: 7, c: 8)
1
[2, 3, 4]
5
6
{:b => 7, :c => 8}

आर्गुमेंट को गलत क्रम में लिखने पर एरर मिलेगी:

def my_method(a:, **keyword_arguments, first, *arguments, last)
  arguments
end

my_method(1, 2, 3, 4, a: 5)

syntax error, unexpected local variable or method, expecting & or '&'
... my_method(a:, **keyword_arguments, first, *arguments, last)

मेथड कॉल में डीकंपोज़ करना

आप मेथड कॉल में आर्गुमेंट की ऐरे को खोलने के लिए स्प्लैट ऑपरेटर (*) इस्तेमाल कर सकते हैं:

def my_method(a, b, c)
  p c
  p b
  p a
end

numbers = [1, 2, 3]
my_method(*numbers)
3
2
1

आप मेथड कॉल में आर्गुमेंट की डिक्शनरी को खोलने के लिए डबल स्प्लैट ऑपरेटर (**) भी इस्तेमाल कर सकते हैं:

def my_method(a:, b:, c:)
  p c
  p b
  p a
end

numbers = {a: 1, b: 2, c: 3}
my_method(**numbers)
3
2
1
GitHub के ज़रिए संपादित करें यह लिंक नई विंडो या टैब में खुलता है।

मल्टीपल असाइनमेंट और डीकंपोज़िशन सीखिए