ruby on rails - রুবি রেফারেন্স দ্বারা বা মান দ্বারা পাস?



ruby-on-rails pass-by-reference (8)

@user.update_languages(params[:language][:language1], 
                       params[:language][:language2], 
                       params[:language][:language3])
lang_errors = @user.errors
logger.debug "--------------------LANG_ERRORS----------101-------------" 
                + lang_errors.full_messages.inspect

if params[:user]
  @user.state = params[:user][:state]
  success = success & @user.save
end
logger.debug "--------------------LANG_ERRORS-------------102----------" 
                + lang_errors.full_messages.inspect

if lang_errors.full_messages.empty?

lang_errors অবজেক্টটি lang_errors পরিবর্তনশীলদের update_lanugages পদ্ধতিতে যোগ করে। যখন আমি lang_errors বস্তুর উপর একটি সংরক্ষণ সঞ্চালন করি তখন আমি lang_errors পরিবর্তনশীল মধ্যে প্রাথমিকভাবে সংরক্ষণ করা ত্রুটিগুলি হারাতে পারি।

যদিও আমি যা করার চেষ্টা করছি তা হ্যাকের বেশি হবে (যা কাজ বলে মনে হচ্ছে না)। আমি বুঝতে চাই কেন পরিবর্তনশীল মান ধুয়ে ফেলা হয়। আমি রেফারেন্স দ্বারা পাস বুঝতে তাই আমি জানতে চাই যে মূল্য পরিবর্তনশীল ছাড়া মান পরিবর্তন করা যাবে কিভাবে।


Answer #1

রুবি রেফারেন্স দ্বারা বা মান দ্বারা পাস?

রুবি পাস দ্বারা রেফারেন্স হয়। সর্বদা. কোন আশা নাই. না ifs। কোন কিন্তু নাই.

এখানে একটি সাধারণ প্রোগ্রাম যা এই সত্যটি প্রদর্শন করে:

def foo(bar)
  bar.object_id
end

baz = 'value'

puts "#{baz.object_id} Ruby is pass-by-reference #{foo(baz)} because object_id's (memory addresses) are always the same ;)"

=> 2279146940 রুবি পাস-বাই-রেফারেন্স 2279146940 কারণ বস্তু_আইডি (মেমরি ঠিকানা) সবসময় একই থাকে;)

def bar(babar)
  babar.replace("reference")
end

bar(baz)

puts "some people don't realize it's reference because local assignment can take precedence, but it's clearly pass-by-#{baz}"

=> কিছু লোক এটির রেফারেন্সটি উপলব্ধি করে না কারণ স্থানীয় নিয়োগটি অগ্রাধিকার নিতে পারে তবে এটি স্পষ্টভাবে পাস-রেফারেন্স


Answer #2

রুবি রেফারেন্স দ্বারা বা মান দ্বারা পাস?

রুবি পাস-বাই-মান। সর্বদা. কোন আশা নাই. না ifs। কোন কিন্তু নাই.

এখানে একটি সাধারণ প্রোগ্রাম যা এই সত্যটি প্রদর্শন করে:

def foo(bar)
  bar = 'reference'
end

baz = 'value'

foo(baz)

puts "Ruby is pass-by-#{baz}"
# Ruby is pass-by-value

Answer #3

অন্য উত্তরদাতারা সব ঠিক আছে, কিন্তু একজন বন্ধু আমাকে এটিকে ব্যাখ্যা করার জন্য এবং কীভাবে রুবি কীভাবে চলতে থাকে তা বোঝার জন্য এটি কীভাবে উড়িয়ে দেয়, তাই আমি ভাবলাম আমি তার জন্য লিখেছি এমন কিছু সহজ ছবি / ব্যাখ্যা ভাগ করবো (দৈর্ঘ্যের জন্য ক্ষমাপ্রার্থী) এবং সম্ভবত কিছু oversimplification):

প্রশ্ন 1: যখন আপনি 'foo' এর একটি মানের জন্য একটি নতুন পরিবর্তনশীল str নির্দিষ্ট করেন তখন কী হয়?

str = 'foo'
str.object_id # => 2000

উত্তর: str নামক একটি লেবেলটি 'foo' বস্তুর পয়েন্টগুলি তৈরি করে, যা এই রুবি ইন্টারপ্রেটারের অবস্থা মেমরি অবস্থান 2000 এ হতে পারে।

প্রশ্ন 2: যখন আপনি বিদ্যমান পরিবর্তনশীল str = ব্যবহার করে একটি নতুন বস্তুর বরাদ্দ করেন তখন কি হয়?

str = 'bar'.tap{|b| puts "bar: #{b.object_id}"} # bar: 2002
str.object_id # => 2002

উত্তর: লেবেল str এখন এখন একটি ভিন্ন বস্তুর দিকে নির্দেশ করে।

প্রশ্ন 3: যখন আপনি একটি নতুন পরিবর্তনশীল = str দিতে হবে তখন কি হবে?

str2 = str
str2.object_id # => 2002

উত্তর: str2 নামক একটি নতুন লেবেলটি একই বস্তুতে str হিসাবে তৈরি হয়।

প্রশ্ন 4: str এবং str2 দ্বারা উল্লিখিত বস্তু পরিবর্তিত হলে কি হবে?

str2.replace 'baz'
str2 # => 'baz'
str  # => 'baz'
str.object_id # => 2002
str2.object_id # => 2002

উত্তর: উভয় লেবেল একই বস্তুর দিকে নির্দেশ করে, তবে সেই বস্তুটি নিজেই পরিবর্তিত হয়েছে (এর বিষয়বস্তু অন্য কিছু হতে পরিবর্তিত হয়েছে)।

কিভাবে এই মূল প্রশ্ন সম্পর্কিত?

এটি মূলত Q3 / Q4 তে যা ঘটে তা একই রকম। পদ্ধতিটি তার নিজস্ব ব্যক্তিগত কপিটি পরিবর্তনশীল / লেবেল ( str2 ) -এ পাস করে যা এটি ( str ) পাস করে। লেবেল str points কে কোন বস্তুটি পরিবর্তন করতে পারে তা পরিবর্তন করতে পারে না, তবে এটি এমন বস্তুর সামগ্রীগুলিকে পরিবর্তন করতে পারে যা তারা উভয়ই ধারণ করতে পারে:

str = 'foo'

def mutate(str2)
  puts "str2: #{str2.object_id}"
  str2.replace 'bar'
  str2 = 'baz'
  puts "str2: #{str2.object_id}"
end

str.object_id # => 2004
mutate(str) # str2: 2004, str2: 2006
str # => "bar"
str.object_id # => 2004

Answer #4

ইতিমধ্যে কিছু মহান উত্তর আছে, তবে আমি এই বিষয়ের উপর কর্তৃপক্ষের এক জোড়া সংজ্ঞা পোস্ট করতে চাই, কিন্তু কর্তৃপক্ষ মাতজ (রুবি সৃষ্টিকর্তা) এবং ডেভিড ফ্লানগনকে তাদের চমৎকার ও'লিলে বইয়ের অর্থ বলে কেউ কি ব্যাখ্যা করতে পারে, রুবি প্রোগ্রামিং ভাষা

[3.8.1 থেকে: অবজেক্ট রেফারেন্স]

যখন আপনি রুবিতে একটি পদ্ধতিতে একটি বস্তু পাস করেন, এটি একটি বস্তু রেফারেন্স যা পদ্ধতিতে প্রেরিত হয়। এটি বস্তু নিজেই নয়, এবং এটি বস্তুর রেফারেন্সের একটি রেফারেন্স নয়। এটি করার আরেকটি উপায় হল পদ্ধতির আর্গুমেন্টগুলি রেফারেন্সের পরিবর্তে মান দ্বারা পাস করা হয় , তবে পাস করা মান বস্তুগুলির উল্লেখ।

কারণ বস্তুর রেফারেন্স পদ্ধতিতে পাস করা হয়, পদ্ধতি অন্তর্নিহিত বস্তু সংশোধন করতে সেই রেফারেন্সগুলি ব্যবহার করতে পারে। পদ্ধতি ফিরে যখন এই পরিবর্তন তারপর দৃশ্যমান হয়।

এই সব শেষ অনুচ্ছেদ পর্যন্ত, এবং বিশেষত যে শেষ বাক্য পর্যন্ত আমাকে জ্ঞান করে তোলে। এই ভাল বিভ্রান্তিকর এ, এবং খারাপ confounding হয়। কিভাবে, যে কোন উপায়ে, পরিবর্তন দ্বারা বাইরের রেফারেন্স অন্তর্নিহিত বস্তু পরিবর্তন করতে পারে?


Answer #5

এটি উল্লেখ করা উচিত যে মানটি মূল মান পরিবর্তন করার জন্য আপনাকে "প্রতিস্থাপন" পদ্ধতিটি ব্যবহার করতে হবে না। যদি আপনি হ্যাশের জন্য হ্যাশ মানগুলির একটি বরাদ্দ করেন তবে আপনি মূল মান পরিবর্তন করছেন।

def my_foo(a_hash)
  a_hash["test"]="reference"
end;

hash = {"test"=>"value"}
my_foo(hash)
puts "Ruby is pass-by-#{hash["test"]}"

Answer #6

পরামিতি মূল রেফারেন্স একটি কপি। সুতরাং, আপনি মান পরিবর্তন করতে পারেন, কিন্তু মূল রেফারেন্স পরিবর্তন করতে পারবেন না।


Answer #7

রুবি একটি কঠোর অর্থে পাস-বাই-মান, কিন্তু মান উল্লেখ করা হয়।

এটি " পাস-রেফারেন্স-বাই-মান " বলা যেতে পারে। এই নিবন্ধটি আমার কাছে সবচেয়ে ভাল ব্যাখ্যা রয়েছে: robertheaton.com/2014/07/22/…

পাস-রেফারেন্স-বাই-মান সংক্ষিপ্তভাবে নিম্নরূপ ব্যাখ্যা করা যেতে পারে:

একটি ফাংশন কলার দ্বারা ব্যবহৃত মেমরির একই বস্তুর (এবং অ্যাক্সেস করবে) একটি রেফারেন্স পায়। যাইহোক, এই বক্সটি কলকারী এই বস্তুটি সংরক্ষণ করছে না; পাস-মান-বাই-মান হিসাবে, ফাংশন নিজস্ব বাক্স সরবরাহ করে এবং নিজের জন্য একটি নতুন পরিবর্তনশীল তৈরি করে।

ফলে আচরণ প্রকৃতপক্ষে পাস-বাই-রেফারেন্স এবং পাস-বাই-মানের ক্লাসিক্যাল সংজ্ঞাগুলির সমন্বয়।


Answer #8

রুবি ব্যাখ্যা করা হয়। ভেরিয়েবল তথ্য রেফারেন্স, কিন্তু তথ্য নিজেই হয় না। এটি বিভিন্ন ধরনের তথ্যগুলির জন্য একই পরিবর্তনশীল ব্যবহার করে।

Lhs = rhs বরাদ্দকরণের পরে তথ্যটি না rhs রেফারেন্স কপি করে। এটি অন্যান্য ভাষায় ভিন্ন, যেমন সি, যেখানে নিয়োগটি rhs থেকে lhs এ একটি ডাটা অনুলিপি করে।

সুতরাং ফাংশন কল জন্য, পরিবর্তনশীল পাস, এক্স, প্রকৃতপক্ষে ফাংশন একটি স্থানীয় পরিবর্তনশীল মধ্যে অনুলিপি করা হয়, কিন্তু এক্স একটি রেফারেন্স। তারপর একই তথ্য উল্লেখ উভয়, রেফারেন্স দুটি কপি হবে। এক কলার, ফাংশন এক হতে হবে।

ফাংশনে অ্যাসাইনমেন্ট এক্স এর ফাংশনের সংস্করণে একটি নতুন রেফারেন্স অনুলিপি করবে। এর পরে x এর কলার সংস্করণটি অপরিবর্তিত থাকে। এটি এখনও মূল তথ্য একটি রেফারেন্স।

বিপরীতে, x এ .replace পদ্ধতি ব্যবহার করে রুবি একটি ডাটা কপি করতে হবে। যদি প্রতিস্থাপন কোন নতুন কার্যনির্বাহনের পূর্বে ব্যবহার করা হয় তবে প্রকৃতপক্ষে কলকারী তার সংস্করণে ডেটা পরিবর্তন দেখতে পাবে।

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

'কল দ্বারা মান' বা 'কল দ্বারা রেফারেন্স' এখানে বিভ্রান্ত হয় কারণ '=' এর উপর বিভ্রান্তি সংকলিত ভাষায় '=' একটি তথ্য অনুলিপি। এখানে এই ব্যাখ্যাকৃত ভাষা '=' একটি রেফারেন্স কপি। উদাহরণস্বরূপ, আপনার একটি রেফারেন্স অনুলিপি অনুসরণ করা হয়েছে যা '=' যদিও '=' যা আসল রেফারেন্সে পাঠানো হয়েছে এবং তারপরে লোকেরা এটি সম্পর্কে কথা বলছে যেমন '=' একটি ডেটা অনুলিপি ছিল।

সংজ্ঞাগুলির সাথে সামঞ্জস্যপূর্ণ হতে হলে আমাদের অবশ্যই '.replace' দিয়ে রাখতে হবে কারণ এটি একটি ডেটা কপি। '.Replace' এর দৃষ্টিকোণ থেকে আমরা দেখি এটি আসলে রেফারেন্স দ্বারা পাস করা হয়েছে। উপরন্তু, যদি আমরা ডিবাগারে দিয়ে হেঁটে যাই তবে আমরা রেফারেন্সগুলি পাস করতে দেখি, কারণ ভেরিয়েবলগুলি রেফারেন্স।

যাইহোক, যদি আমাদের রেফারেন্সের ফ্রেম হিসাবে '=' রাখা দরকার, তবে প্রকৃতপক্ষে আমরা একটি অ্যাসাইনমেন্ট না হওয়া পর্যন্ত পাস হওয়া ডেটা দেখতে পাব, এবং তারপরে আমরা নিয়োগের পরে এটি আর দেখতে পাব না যখন কলারের তথ্য অপরিবর্তিত থাকে। একটি আচরণগত পর্যায়ে এটি মান দ্বারা পাস করা হয় যতক্ষণ আমরা সম্মিলিত মানটিকে সম্মিলিত হিসাবে বিবেচনা করি না - আমরা একক নিয়োগে অন্য অংশটি পরিবর্তন করার সময় এটির অংশটি রাখতে সক্ষম হব না (যে বরাদ্দ হিসাবে রেফারেন্স পরিবর্তন এবং মূল সুযোগ সুযোগ আউট)। এছাড়াও একটি wart হবে, যে ক্ষেত্রে বস্তুর ভেরিয়েবল রেফারেন্স হবে, সব ভেরিয়েবল হিসাবে। অতএব আমরা 'মান দ্বারা রেফারেন্স' পাস সম্পর্কে কথা বলার জন্য বাধ্য করা হবে এবং সম্পর্কিত লোকেশন ব্যবহার করতে হবে।





pass-by-reference