রুবিতে নিম্নলিখিত কোডটির অর্থ কী?
||=
সিনট্যাক্সটির কি এর কোনও অর্থ বা কারণ রয়েছে?
রুবিতে নিম্নলিখিত কোডটির অর্থ কী?
||=
সিনট্যাক্সটির কি এর কোনও অর্থ বা কারণ রয়েছে?
উত্তর:
এই প্রশ্নটি প্রায়শই রুবি মেলিং-তালিকা এবং রুবি ব্লগগুলিতে আলোচিত হয়েছে যে রুবি মেলিং-তালিকায় এখন এমনকি থ্রেড রয়েছে যার একমাত্র উদ্দেশ্য রুবি মেইলিং-তালিকার অন্যান্য থ্রেডের লিঙ্ক সংগ্রহ করা যা এই সমস্যাটি নিয়ে আলোচনা করে that ।
এখানে একটি: || = (বা সমান) থ্রেড এবং পৃষ্ঠাগুলির সুনির্দিষ্ট তালিকা
আপনি যদি সত্যিই জানতে কি ঘটছে চাই, এর "সংক্ষিপ্ত বরাদ্দকরণ" অনুচ্ছেদ 11.4.2.3 কটাক্ষপাত করা রুবি ভাষা খসড়া স্পেসিফিকেশন ।
প্রথম অনুমান হিসাবে,
a ||= b
সমতুল্য
a || a = b
এবং সমতুল্য নয়
a = a || b
তবে এটি কেবলমাত্র প্রথম অনুমান, বিশেষত যদি a
অপরিজ্ঞাত থাকে। শব্দার্থবিজ্ঞানগুলি এটি একটি সাধারণ ভেরিয়েবল অ্যাসাইনমেন্ট, কোনও পদ্ধতি অ্যাসাইনমেন্ট বা ইনডেক্সিং অ্যাসাইনমেন্টের উপর নির্ভর করেও পৃথক:
a ||= b
a.c ||= b
a[c] ||= b
সবাইকে আলাদাভাবে চিকিত্সা করা হয়।
a = false; a ||= true
করে না কি আপনার উত্তর বলছেন একটি "সামান্য পার্থক্য" করে না।
a ||= b
ইহা একটি শর্তাধীন নিয়োগ অপারেটর । এর অর্থ যদি অপরিজ্ঞাতa
বা মিথ্যা হয় তবে মূল্যায়ন করুন b
এবং ফলাফলটিতে সেট a
করুন । সমানভাবে, যদি a
সংজ্ঞায়িত হয় এবং সত্যের কাছে মূল্যায়ন হয় তবে b
মূল্যায়ন হয় না এবং কোনও কার্য সম্পাদনও ঘটে না। উদাহরণ স্বরূপ:
a ||= nil # => nil
a ||= 0 # => 0
a ||= 2 # => 0
foo = false # => false
foo ||= true # => true
foo ||= false # => true
বিভ্রান্তিকরভাবে, এটি অন্যান্য অ্যাসাইনমেন্ট অপারেটরগুলির (যেমন +=
) এর মতো দেখতে লাগে তবে ভিন্ন আচরণ করে।
a += b
অনুবাদ a = a + b
a ||= b
মোটামুটি অনুবাদ a || a = b
এটি জন্য একটি কাছাকাছি শর্টহ্যান্ড a || a = b
। পার্থক্য হচ্ছে, যখন a
undefined হয়, a || a = b
বাড়াতে হবে NameError
, যেহেতু a ||= b
সেট a
করতে b
। এই পার্থক্যটি গুরুত্বহীন যদি a
এবং b
উভয় স্থানীয় ভেরিয়েবল হয় তবে তা যদি কোনও শ্রেণীর গেটর / সেটার পদ্ধতি হয় তবে তা তাৎপর্যপূর্ণ।
আরও পড়া:
h = Hash.new(0); h[1] ||= 2
। এখন h[1] = h[1] || 2
বনাম সম্ভাব্য দুটি বিবেচনা করুন h[1] || h[1] = 2
। উভয় এক্সপ্রেশন মূল্যায়ন করে 0
তবে প্রথম অকারণে হ্যাশের আকার বাড়িয়ে তোলে। সম্ভবত সে কারণেই ম্যাটজ ||=
দ্বিতীয় বিস্তারের মতো আচরণ করা বেছে নিয়েছিল । (আমি এটি অন্য উত্তরের সাথে সংযুক্ত থ্রেডগুলির একটি উদাহরণের ভিত্তিতে তৈরি করেছি))
a || a = b
একটি সংজ্ঞায়িত NameError
যদি উত্থাপন a
। a ||= b
না, পরিবর্তে এটি আরম্ভ করে a
সেট করে দেয় b
। আমি যতদূর জানি দুজনের মধ্যে এটিই একমাত্র পার্থক্য। একইভাবে, a = a || b
এবং a ||= b
আমি যে সম্পর্কে সচেতন তার মধ্যে কেবলমাত্র তফাতটি হ'ল যদি a=
কোনও পদ্ধতি হয় তবে তা কী a
ফিরে আসে তা নির্বিশেষে বলা হবে । এছাড়াও, শুধুমাত্র মধ্যে পার্থক্য a = b unless a
এবং a ||= b
আমি সচেতন আছি যে যে বিবৃতি মূল্যায়ন হয় nil
পরিবর্তে a
যদি a
truthy হয়। প্রচুর অনুমান, তবে কিছুটা সমান নয় ...
a ||= b
নিম্নলিখিত প্রতিটি লাইনের মতোই মূল্যায়ন করে
a || a = b
a ? a : a = b
if a then a else a = b end
-
অন্য দিকে,
a = a || b
নিম্নলিখিত প্রতিটি লাইনের মতোই মূল্যায়ন করে
a = a ? a : b
if a then a = a else a = b end
-
সম্পাদনা করুন: আজেদী 32 মন্তব্যগুলিতে যেমন উল্লেখ করেছেন, এটি কেবল তখনই সত্য ধারণ করে যদি: 1. ক একটি সংজ্ঞায়িত ভেরিয়েবল হয়। ২.এক সময় এবং দু'বার মূল্যায়ন করার ফলে প্রোগ্রাম বা সিস্টেমের ক্ষেত্রে পার্থক্য হয় না।
a
মিথ্যা / শূন্য / অপরিজ্ঞাত হয় তবে এটি দুটিবার মূল্যায়ন করা হয়। (তবে আমি রুবিকে চিনি না, সুতরাং আমি জানি না যে ল্যাভেলুগুলি ঠিক 'মূল্যায়ন' করা যায় ...)
a || a = b
, a ? a : a = b
, if a then a else a = b end
, এবং if a then a = a else a = b end
একটি ত্রুটি যদি নিক্ষেপ করা হবে a
undefined হয়, যেহেতু a ||= b
এবং a = a || b
হবে না। এছাড়াও, a || a = b
, a ? a : a = b
, if a then a else a = b end
, a = a ? a : b
, এবং if a then a = a else a = b end
মূল্যায়ন a
দুইবার যখন a
truthy হয়, যেহেতু a ||= b
এবং a = a || b
না।
a || a = b
মূল্যায়ন করবে না । a
a
the end state will be equivalent after the whole line has been evaluated
যদিও এটি অগত্যা সত্য নয়। যদি a
একটি পদ্ধতি হয়? পদ্ধতিগুলির পার্শ্ব প্রতিক্রিয়া হতে পারে। উদাহরণস্বরূপ public; def a=n; @a=n; end; def a; @a+=1; end; self.a = 5
, self.a ||= b
6 ফিরে আসবে তবে self.a ? self.a : self.a = b
ফিরে আসবে 7
এর অর্থ বা সমান এটি বাম দিকের মান সংজ্ঞায়িত হয়েছে কিনা তা পরীক্ষা করে দেখুন, তবে এটি ব্যবহার করুন। যদি তা না হয় তবে ডানদিকে মানটি ব্যবহার করুন। আপনি মডেলগুলিতে উদাহরণের ভেরিয়েবলগুলি ক্যাশে এটি রেলগুলিতে ব্যবহার করতে পারেন।
একটি দ্রুত রেল-ভিত্তিক উদাহরণ, যেখানে আমরা বর্তমানে লগ ইন করা ব্যবহারকারী আনার জন্য একটি ফাংশন তৈরি করি:
class User > ActiveRecord::Base
def current_user
@current_user ||= User.find_by_id(session[:user_id])
end
end
এটি @cre_user দৃষ্টান্ত পরিবর্তনশীলটি সেট করা আছে কিনা তা পরীক্ষা করে দেখুন। যদি এটি হয়, এটি এটি ফিরিয়ে দেবে, যার ফলে একটি ডেটাবেস কল সংরক্ষণ করবে। এটি যদি সেট না করা থাকে তবে আমরা কল করি এবং তারপরে @ ক্রিয়াল_ইউসার ভেরিয়েবল সেট করি। এটি সত্যিই একটি সহজ ক্যাচিং কৌশল তবে আপনি যখন একাধিকবার অ্যাপ্লিকেশন জুড়ে একই উদাহরণটি পরিবর্তনশীল আনছেন তখন দুর্দান্ত।
undefined
, তবে চালিয়ে যায়false
এবংnil
যা প্রাসঙ্গিক নাও হতে পারে current_user
, তবে বিশেষত false
অন্যান্য ক্ষেত্রে এটি অপ্রত্যাশিত হতে পারে
x ||= y
হয়
x || x = y
"যদি x মিথ্যা বা অপরিজ্ঞাত থাকে তবে x পয়েন্টে y"
সুনির্দিষ্ট হওয়ার a ||= b
অর্থ, "যদি a
অপরিজ্ঞাত বা মিথ্যা হয় ( false
বাnil
) হয় তবে সেট a
করা b
এবং মূল্যায়ন (অর্থাত্ প্রত্যাবর্তন) b
, অন্যথায় মূল্যায়ন করুনa
"।
অন্যরা প্রায়শই এটি a ||= b
বলে a || a = b
বা এটির সমতুল্য বলে ব্যাখ্যা করার চেষ্টা করে a = a || b
। এই সমতাগুলি ধারণাটি বোঝার জন্য সহায়ক হতে পারে তবে সচেতন হন যে তারা সমস্ত অবস্থার অধীনে সঠিক নয় । আমাকে ব্যাখ্যা করার অনুমতি দিন:
a ||= b
⇔ a || a = b
?
এই বিবৃতিগুলির আচরণের a
পরিবর্তন হয় যখন কোনও অপরিবর্তিত স্থানীয় ভেরিয়েবল হয়। সেক্ষেত্রে, a ||= b
সেট a
করা হবে b
(এবং এটিতে মূল্যায়ন করুন b
), যেখানে a || a = b
উত্থাপন হবেNameError: undefined local variable or method 'a' for main:Object
।
a ||= b
⇔ a = a || b
?
এই বিবৃতির সমানতা প্রায়ই অধিকৃত হয়, যেহেতু একই ধরনের সমানতা অন্যান্য জন্য সত্য সংক্ষিপ্ত নিয়োগ অপারেটার (অর্থাত +=
, -=
, *=
, /=
, %=
, **=
, &=
, |=
, ^=
, <<=
, এবং >>=
)। যাইহোক, ||=
এই বিবৃতিগুলির আচরণের জন্য পৃথক হতে পারে যখন a=
কোনও বস্তুর কোনও পদ্ধতি এবং a
সত্যবাদী। সেক্ষেত্রে, a ||= b
কিছুই (নির্ণয় ছাড়া অন্য কি করতে হবে a
যেহেতু,) a = a || b
ডাকব a=(a)
উপর a
এর রিসিভার। অন্যরা যেমন উল্লেখ করেছে, কল করার a=a
ক্ষেত্রে পার্শ্বপ্রতিক্রিয়া যেমন হ্যাশগুলিতে কী যুক্ত করা হয় তখন এটি একটি পার্থক্য করতে পারে ।
a ||= b
⇔a = b unless a
??
এই বিবৃতিগুলির আচরণ কেবল যখন a
সত্য হয় তখন তারা যা মূল্যায়ন করে তার মধ্যে তারতম্য। সেক্ষেত্রে, a = b unless a
নির্ণয় করা হবে nil
(যদিও a
, এখনও, সেট করা হইনি আশানুরূপ) যেহেতু a ||= b
নির্ণয় করা হবে a
।
a ||= b
⇔defined?(a) ? (a || a = b) : (a = b)
????
এখনও না. এই বিবৃতিগুলি পৃথক হতে পারে যখন কোনও method_missing
পদ্ধতি বিদ্যমান থাকে যা এর জন্য সত্যবাদী মান দেয় a
। এই ক্ষেত্রে, a ||= b
যাই হোক না কেন নির্ণয় করা হবে method_missing
আয় ও সেট করার চেষ্টা করবেন a
, যেহেতু defined?(a) ? (a || a = b) : (a = b)
সেট হবে a
থেকে b
এবং মূল্যায়নের b
।
ঠিক আছে, ঠিক আছে, তাই কি হয় a ||= b
সমতুল্য? এটি রুবিতে প্রকাশ করার কোনও উপায় আছে কি?
ঠিক আছে, ধরে নিই যে আমি কিছুই উপেক্ষা করছি না, আমি বিশ্বাস করি a ||= b
যে কার্যত ... ( ড্রামরল ) এর সমতুল্য
begin
a = nil if false
a || a = b
end
অপেক্ষা কর! এটির আগে নূপুরের সাথে এটিই কি প্রথম উদাহরণ নয়? ভাল, বেশ না। মনে রাখবেন যে আমি এর আগে কীভাবে বলেছিলাম a ||= b
কেবল a || a = b
যখন a
অপরিজ্ঞাত স্থানীয় ভেরিয়েবলের সমান হয় না ? ভাল, a = nil if false
নিশ্চিত করে যে a
এটি কখনই অপরিবর্তিত নয়, যদিও সেই লাইনটি কখনই কার্যকর হয় না। রুবির স্থানীয় ভেরিয়েবলগুলি নমনীয়ভাবে স্কোপযুক্ত।
(a=b unless a) or a
a
কোনও পদ্ধতি হয় তবে এটি একবারের পরিবর্তে দু'বার কল করা হবে (যদি এটি সত্যিক মানটি প্রথমবারে ফেরত দেয়)। উদাহরণস্বরূপ, a
ফিরে আসতে যদি দীর্ঘ সময় লাগে বা তার পার্শ্ব প্রতিক্রিয়া হয় তবে এর ফলে আচরণগুলি পৃথক হতে পারে ।
b
করারa
অন্য কথায়, RHS এখনও LHS নির্ধারিত নয়, অথবা, LHS এখনও RHS তার মান সেট করে না?
a ||= b
উত্তর আমি ইন্টারনেটে খুঁজে পেয়েছি। ধন্যবাদ।
ধরুন a = 2
এবংb = 3
তারপরে, এর মান a ||= b
হিসাবে ফলস্বরূপ আসবে ।a
2
যেহেতু যখন কোনও মূল্যায়ণ কোন ফলাফলের ফলাফল দেয় না false
বা হয় না nil
.. এজন্য এটি এর মানকে ll
মূল্যায়ন করে না b
।
এখন ধরুন a = nil
এবং b = 3
।
তারপরে a ||= b
ফলাফল হবে 3
অর্থাত্ b
এর মান হিসাবে।
যেহেতু এটির ফলাফলটি প্রথমে এর মান মূল্যায়নের চেষ্টা করে nil
.. সুতরাং এটি মূল্যায়ন করেb
মান ।
রোর অ্যাপে ব্যবহৃত সেরা উদাহরণটি হ'ল:
#To get currently logged in iser
def current_user
@current_user ||= User.find_by_id(session[:user_id])
end
# Make current_user available in templates as a helper
helper_method :current_user
যেখানে, আগে আরম্ভ করা না User.find_by_id(session[:user_id])
হলে এবং যদি বরখাস্ত করা @current_user
হয়।
a || = খ
কোনও মান 'ক' তে উপস্থিত থাকলে তা চিহ্নিত করে এবং আপনি সেই মানটি ব্যবহার করে এটি পরিবর্তন করতে চান না, অন্যথায় যদি 'এ' এর কোনও মান না থাকে তবে 'বি' এর মানটি ব্যবহার করুন।
সরল শব্দগুলি, যদি বাম হাতটি শূন্য না হয় তবে বিদ্যমান মানের দিকে নির্দেশ করুন, অন্যথায় ডানদিকে মানকে নির্দেশ করুন।
a ||= b
সমতুল্য
a || a = b
এবং না
a = a || b
আপনি যখন একটি হ্যাশকে ডিফল্ট দিয়ে সংজ্ঞায়িত করেন এমন পরিস্থিতিতে (হ্যাশ কোনও অপরিজ্ঞাত কীগুলির জন্য ডিফল্টটি ফিরিয়ে দেবে)
a = Hash.new(true) #Which is: {}
আপনি যদি ব্যবহার করেন:
a[10] ||= 10 #same as a[10] || a[10] = 10
একটি এখনও আছে:
{}
তবে আপনি যখন এটি লিখেন:
a[10] = a[10] || 10
একটি হয়ে:
{10 => true}
কারণ আপনি নিজের মানটি কীতে নির্ধারণ করেছেন 10
, যা সত্যের ডিফল্ট, তাই এখন হ্যাশটি 10
কখনই প্রথম স্থানে অ্যাসাইনমেন্টটি সম্পাদন না করে চাবিটির জন্য সংজ্ঞায়িত করা হয় ।
দয়া করে মনে রাখবেন যে ||=
এটি কোনও পারমাণবিক অপারেশন নয় এবং তাই এটি থ্রেডটি নিরাপদ নয়। থাম্বের নিয়ম হিসাবে, এটি ক্লাস পদ্ধতিগুলির জন্য ব্যবহার করবেন না।
এটি ডিফল্ট অ্যাসাইনমেন্ট নোটেশন
উদাহরণস্বরূপ: x || = 1
এটি এক্স নিল কিনা তা পরীক্ষা করে দেখবে। যদি এক্স সত্যই শূন্য হয় তবে এটি নতুন মানটি নির্ধারণ করবে (আমাদের উদাহরণে 1)
আরও সুস্পষ্ট:
যদি x == নীল
x = 1 টি
শেষ হয়
nil
বা false
না, কেবলnil
||=
বাম == শূন্য হলে (বা অপরিজ্ঞাত বা মিথ্যা) কেবলমাত্র ডানদিকে মান নির্ধারণ করে।
এই রুবি-ল্যাং সিনট্যাক্স। সঠিক উত্তরটি হল রুবি-ল্যাং ডকুমেন্টেশন যাচাই করা। অন্যান্য সমস্ত ব্যাখ্যা অবলম্বন করে ।
"রুবি-ল্যাং ডকস সংক্ষেপিত অ্যাসাইনমেন্ট"।
https://docs.ruby-lang.org/en/2.4.0/syntax/assignment_rdoc.html#label-Abbreviated+Assignment
b = 5
a ||= b
এটি অনুবাদ করে:
a = a || b
যা হবে
a = nil || 5
তাই শেষ পর্যন্ত
a = 5
এখন যদি আপনি এটি আবার কল করেন:
a ||= b
a = a || b
a = 5 || 5
a = 5
b = 6
এখন যদি আপনি এটি আবার কল করেন:
a ||= b
a = a || b
a = 5 || 6
a = 5
যদি আপনি পর্যবেক্ষণ করেন, b
মান নির্ধারিত হবে না a
। a
এখনও থাকবে 5
।
এটি একটি মেমোয়াইজেশন প্যাটার্ন যা রুবিতে অ্যাক্সেসরদের গতি বাড়ানোর জন্য ব্যবহৃত হচ্ছে।
def users
@users ||= User.all
end
এটি মূলত:
@users = @users || User.all
সুতরাং আপনি যখন প্রথম এই পদ্ধতিতে কল করবেন তখন আপনি ডাটাবেসে একটি কল করবেন।
এই পদ্ধতিতে ভবিষ্যতের কলগুলি কেবলমাত্র @users
ভেরিয়েবলের মান প্রদান করবে ।
||=
কন্ডিশনাল এসাইনমেন্ট অপারেটর বলে।
এটি মূলত হিসাবে =
ব্যতিক্রম হিসাবে কাজ করে যে একটি ভেরিয়েবল ইতিমধ্যে নির্ধারিত হয়ে থাকলে এটি কিছুই করবে না।
প্রথম উদাহরণ:
x ||= 10
দ্বিতীয় উদাহরণ:
x = 20
x ||= 10
প্রথম উদাহরণে x
এখন 10 এর সমান। তবে দ্বিতীয় উদাহরণটিতে x
ইতিমধ্যে 20 হিসাবে সংজ্ঞায়িত করা হয়েছে। সুতরাং শর্তসাপেক্ষ অপারেটরের কোনও প্রভাব নেই। x
এখনো 20 চলমান পরে হয় x ||= 10
।
a ||= b
বলা a = b if a.nil?
বা হিসাবে একইa = b unless a
তবে সমস্ত 3 টি বিকল্প কী একই কর্মক্ষমতা দেখায়? এই সাথে রুবি 2.5.1
1000000.times do
a ||= 1
a ||= 1
a ||= 1
a ||= 1
a ||= 1
a ||= 1
a ||= 1
a ||= 1
a ||= 1
a ||= 1
end
আমার পিসিতে 0.099 সেকেন্ড সময় লাগে while
1000000.times do
a = 1 unless a
a = 1 unless a
a = 1 unless a
a = 1 unless a
a = 1 unless a
a = 1 unless a
a = 1 unless a
a = 1 unless a
a = 1 unless a
a = 1 unless a
end
0.062 সেকেন্ড লাগে। এটি প্রায় 40% দ্রুত।
এবং তারপরে আমাদেরও রয়েছে:
1000000.times do
a = 1 if a.nil?
a = 1 if a.nil?
a = 1 if a.nil?
a = 1 if a.nil?
a = 1 if a.nil?
a = 1 if a.nil?
a = 1 if a.nil?
a = 1 if a.nil?
a = 1 if a.nil?
a = 1 if a.nil?
end
যা 0.166 সেকেন্ড নেয়।
এটি সাধারণভাবে একটি উল্লেখযোগ্য পারফরম্যান্স প্রভাব ফেলবে না এমন নয়, তবে আপনার যদি শেষের কিছুটা অপ্টিমাইজেশনের প্রয়োজন হয় তবে এই ফলাফলটি বিবেচনা করুন। উপায় দ্বারা: a = 1 unless a
নবজাতকের জন্য পড়া সহজ, এটি স্ব-বর্ণনামূলক।
নোট 1: অ্যাসাইনমেন্ট লাইনটি একাধিকবার পুনরাবৃত্তি করার কারণটি হ'ল সময়টি পরিমাপ করা লুপের ওভারহেড হ্রাস করা।
দ্রষ্টব্য 2: a=nil
প্রতিটি অ্যাসাইনমেন্টের আগে যদি আমি শূন্য না করি তবে ফলাফলগুলি সমান ।