রুবি কীভাবে দুটি মান ফিরিয়ে দেয়?


95

যখনই আমি একটি অ্যারেতে মানগুলি অদলবদল করি, আমি নিশ্চিত হয়েছি যে আমি মানগুলির একটি রেফারেন্স ভেরিয়েবলের মধ্যে সঞ্চিত করেছি। তবে আমি দেখতে পেয়েছি যে রুবি দুটি মান ফিরিয়ে আনার পাশাপাশি স্বয়ংক্রিয়ভাবে দুটি মান পরিবর্তন করতে পারে। উদাহরণ স্বরূপ,

array = [1, 3, 5 , 6 ,7]
array[0], array[1] = array[1] , array[0] #=> [3, 1] 

আমি ভাবছিলাম যে রুবি এটি কী করে।


9
প্রযুক্তিগতভাবে রুবি দুটি মান ফিরিয়ে দেয় না। এটি একটি অ্যারে ফেরত দিতে পারে যা দুটি ভেরিয়েবলের জন্য নির্ধারিত হয়।
চার্লস

উত্তর:


166

অন্যান্য ভাষার মতো নয়, রুবিতে যে কোনও পদ্ধতি কলের রিটার্ন মান সর্বদা একটি বস্তু। এটি সম্ভব কারণ রুবির সমস্ত কিছুর মতোই nilনিজেও একটি বস্তু।

তিনটি বুনিয়াদি নিদর্শন রয়েছে যা আপনি দেখতে পাবেন। কোনও নির্দিষ্ট মান ফেরত দেওয়া:

def nothing
end

nothing
# => nil

একটি একক মান প্রদান:

def single
  1
end

x = single
# => 1

এটি অন্যান্য প্রোগ্রামিং ভাষা থেকে আপনি কী প্রত্যাশা করবেন তার সাথে সঙ্গতিপূর্ণ।

একাধিক রিটার্ন মানগুলি নিয়ে কাজ করার সময় জিনিসগুলি কিছুটা আলাদা হয়ে যায়। এগুলি স্পষ্টভাবে নির্দিষ্ট করা দরকার:

def multiple
  return 1, 2
end

x = multiple
# => [ 1, 2 ]
x
# => [ 1, 2 ]

এমন এক কল করার সময় যাতে একাধিক মান ফিরে আসে, আপনি সেগুলি স্বাধীন ভেরিয়েবলগুলিতে বিভক্ত করতে পারেন:

x, y = multiple
# => [ 1, 2 ]
x
# => 1
y
# => 2

এই কৌশলটি আপনি যে ধরণের প্রতিস্থাপনের কথা বলছেন তার জন্যও কাজ করে:

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

8
আপনি সিএ স্পষ্টভাবে একটি অ্যারে ফিরিয়ে দেন [1, 2]এবং এটি উপরের উদাহরণগুলির মতো কাজ করবে।
হাউলেথ

6
@ হাইলেথ একটি ভাল পর্যবেক্ষণ আমার এটা পরিষ্কার করে দেওয়া উচিত যে 1,2নিজে থেকে অবৈধ, তবে উভয়ই return 1,2বা [1,2]কাজ করে।
tadman

51

না, রুবি আসলে দুটি বস্তু ফেরত সমর্থন করে না। (বিটিডাব্লু: আপনি ভেরিয়েবলগুলি নয়, বস্তুগুলি ফিরিয়ে দিন More

এটি সমান্তরাল কার্যভার সমর্থন করে। যদি আপনার একটি কার্যভারের ডানদিকে একাধিক অবজেক্ট থাকে তবে অবজেক্টগুলি একটিতে সংগ্রহ করা হয় Array:

foo = 1, 2, 3
# is the same as
foo = [1, 2, 3]

আপনার যদি একটি অ্যাসাইনমেন্টের বাম-পাশে একাধিক "টার্গেট" (ভেরিয়েবল বা সেটার পদ্ধতি) থাকে তবে ভেরিয়েবলগুলি ডান-হাতের অংশের সাথে আবদ্ধ হয়ে যায় Array:

a, b, c = ary
# is the same as
a = ary[0]
b = ary[1]
c = ary[2]

ডান হাতটি যদি একটি নাArray হয় তবে এটি to_aryপদ্ধতিটি ব্যবহার করে এটি একটিতে রূপান্তরিত হবে

a, b, c = not_an_ary
# is the same as
ary = not_an_ary.to_ary
a = ary[0]
b = ary[1]
c = ary[2]

এবং যদি আমরা দুজনকে একসাথে রাখি তবে আমরা তা পেয়ে যাই

a, b, c = d, e, f
# is the same as
ary = [d, e, f]
a = ary[0]
b = ary[1]
c = ary[2]

এটি সম্পর্কিত একটি অ্যাসাইনমেন্টের বাম-হাতের স্প্ল্যাট অপারেটর। এর মানে "নিতে সব বাম-উপর উপাদান Arrayডান-দিকে":

a, b, *c = ary
# is the same as
a = ary[0]
b = ary[1]
c = ary.drop(2) # i.e. the rest of the Array

এবং সর্বশেষে তবে সর্বনিম্ন নয়, প্রথম বন্ধনী ব্যবহার করে সমান্তরাল অ্যাসাইনমেন্টগুলি নেস্ট করা যেতে পারে:

a, (b, c), d = ary
# is the same as
a = ary[0]
b, c = ary[1]
d = ary[2]
# which is the same as
a = ary[0]
b = ary[1][0]
c = ary[1][1]
d = ary[2]

আপনি যখন returnকোনও পদ্ধতি থেকে nextবা breakকোনও ব্লক থেকে চলে আসেন, রুবি কোনও অ্যাসাইনমেন্টের ডান হাতের মতো এই জাতীয় আচরণ করবে so

return 1, 2
next 1, 2
break 1, 2
# is the same as
return [1, 2]
next [1, 2]
break [1, 2]

যাইহোক, এটি পদ্ধতি এবং ব্লকগুলির পরামিতি তালিকায়ও কাজ করে (পদ্ধতিগুলি আরও কঠোর এবং ব্লকগুলি কম কঠোর হয়):

def foo(a, (b, c), d) p a, b, c, d end

bar {|a, (b, c), d| p a, b, c, d }

ব্লকগুলি "কম কঠোর" হওয়া উদাহরণস্বরূপ যা Hash#eachকাজ করে। এটা আসলে yieldSA একক দুই উপাদান Arrayকী এবং ব্লক মূল্যের, কিন্তু আমরা সাধারণত লেখার

some_hash.each {|k, v| }

পরিবর্তে

some_hash.each {|(k, v)| }

17

ট্যাডম্যান এবং জার্গ ডব্লু মিটাগ রুবিকে আমার চেয়ে আরও ভাল জানেন, এবং তাদের উত্তরগুলি ভুল নয়, তবে আমি মনে করি না যে তারা ওপি জানতে চেয়েছিল সেগুলির জবাব দিচ্ছে। আমি মনে করি যে যদিও প্রশ্নটি পরিষ্কার ছিল না। আমার বোঝার মধ্যে, ওপি যা জানতে চেয়েছিল তার একাধিক মান ফিরিয়ে দেওয়ার কোনও সম্পর্ক নেই।


আসল প্রশ্নটি হ'ল, আপনি যখন দুটি ভেরিয়েবলের মান aএবং b(বা মূল প্রশ্নের মতো একটি অ্যারেতে দুটি পজিশন) স্যুইচ করতে চান, তখন কেন টেম্পোরাল ভেরিয়েবল ব্যবহার করার প্রয়োজন হয় না temp:

a, b = :foo, :bar
temp = a
a = b
b = temp

তবে সরাসরি করা যেতে পারে:

a, b = :foo, :bar
a, b = b, a

উত্তরটি হ'ল একাধিক কার্যক্রমে পুরো ডান হাতটি পুরো বাম হাতের কার্য সম্পাদনের আগে মূল্যায়ন করা হয় এবং এটি এক এক করে করা হয় না। সুতরাং a, b = b, aসমতুল্য নয় a = b; b = a

অ্যাসাইনমেন্টের আগে প্রথমে পুরো ডান হাতটি মূল্যায়ন করা একটি প্রয়োজনীয়তা যা সামঞ্জস্যতা অনুসরণ করে যখন উভয় পক্ষের =বিভিন্ন সংখ্যক পদ থাকে এবং জার্গ ডব্লু মিতাগের বর্ণনা অপ্রত্যক্ষভাবে এর সাথে সম্পর্কিত হতে পারে তবে এটি মূল বিষয় নয়।


8

আপনার যদি কয়েকটি মান থাকে তবে অ্যারেগুলি একটি ভাল বিকল্প। আপনি যদি ফলাফলের ক্রম না জেনে (এবং বিভ্রান্ত হয়ে পড়ে) একাধিক রিটার্ন মান চান তবে বিকল্প হিসাবে হ্যাশ ফিরিয়ে আনতে হবে যা আপনার পছন্দসই নামের মানগুলি অন্তর্ভুক্ত করে।

যেমন

def make_hash
  x = 1
  y = 2
  {x: x, y: y}
end

hash = make_hash
# => {:x=>1, :y=>2}
hash[:x]
# => 1
hash[:y]
# => 2
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.